个人JAVA学习笔记总结(1)(1)

目录

一、语言基础

java基基础知识

1、java编译过程:

java基础知识

变量:

八大基本数据类型​ :

语言:(运算符)

分支:

结构 :

数组 :

方法:

参数 :

二、面向对象

类、对象 (每天一个新对象)

构造方法

内存管理:

引用 “数组” 类型 :

继承 :

向上造型

方法的重写

package和import

访问控制修饰符:-----------保证数据的安全

final:

static:静态的

静态块 :

static final 常量 :

abstract 抽象

成员内部类 : 应用率低 -----> 了解

匿名内部类 : -----> 大大简化代码

接口

多态

内存管理:由JVM来管理的

面向对象的总结

三大特征

常量池:

二进制

什么是2进制

什么是16进制

补码

位运算

&  与运算

|  运算

>>> 右移位运算

移位运算的数学意义


一、语言基础

java基基础知识

1、java编译过程:

        先经过编译 .java文件,之后生成 .class字节码文件(计算机能看懂的文件)。再由JVM加载 .class并运行。
        特点:一次编译,到处使用,可以在其它平台安装虚拟机。 
2.java分类:

        JVM:java虚拟机,加载并运行 .class
        JRE:java运行环境。=JVM+java系统类库(小零件)
        JDK:java开发工具包。=JRE+编译、运行等命令(JVM)
              (1)运行java程序的最小环境为JRE    
              (2)开发java程序的最小环境为JDK
3.IDAE掏钱(可以破解)
         Eclipse不要钱

         IDE :集成开发环境,一套工具。常见有IDAE、Eclipse
         https://i.csdn.net/#/user-center/collection-list?type=1(CSDN我的收藏)

先建项目,后建包,再建类  (直接建包时输入 包名 . 类名)

java基础知识

变量

         (作用范围在包含它最近的大括号内)
            对变量在用的时候必须先声明并初始化
            命名规范:
            只能包含字母、数字、_和$符,不能以数字开头
            严格区分大小写
            不能使用关键字
            允许中文命名,但不建议,建议"英文的见名知意"、“小驼峰命名法”

小驼峰命名法:第1个单词首字母小写,其余单词首字母大写----------变量、方法(score,myScore

大驼峰命名法/帕斯卡命名法:类所有单词首字母都大写-----------------类(Score,MyScore)

数据类型分为:基本数据类型(八大)、引用数据类型(类 class、接口 interface、数组array)

        1G=1024M(兆)
        1M=1024KB(千字节)
        1KB=1024B(字节)   
        1B=8bit(位)

八大基本数据类型​

由小到大
byte(1)----short(2)----int(4)----long(8)----float(4)----double(8)----char(2)
         转换:强制(大转小)、自动/隐式(小转大)

         变量的同名:作用域重叠时,变量不能同名的

        整数byte,short,char,可以直接赋值,但不能超范围
        类型在运算时,将自动转换为int类型 

语言:(运算符)


        运算符:
        算术:+、-、*、/ 、%、++、--
        ++a(先加后输出)
        a++(先输出后加)(在输出(sout)语句中适用)
        单独出现只加一         (同上)
        关系:>、<、>=、<=、==、!=
        逻辑:&& (与 ; 见假为假)、|| (或 ; 见真为真)、!(非; 取反)

  单&,当括号前一个条件为假时,不会运行后面的条件,直接输出

  单| ,当括号前一个条件为真时,不会运行后面的条件,直接输出

        赋值:=(简单)、(扩展)+=、-=、*=、/=、%=
注:扩展赋值自带强转功能

        字符串连接:+

        条件/三目:boolean ?数1 :数2

分支

if(boolean){
       } elae if(boolean){
       }······


        switch(xx){
            case xx:
                输出语句或者其它
            ......
        }

结构 :

顺序结构:从上往下逐行执行,每句必走
分支结构:有条件的执行某语句,并非每句必走
循环结构:for、while、do...while(最少走一次)
循环三要素:循环变量的初始化
                      循环的条件(以循环变量为基础)
                      循环变量的改变(向着循环的结束变)
        break:跳出switch,结束
        continue:跳出本次循环,进入下一次循环

如何选择循环来写代码
        先看循环是否与次数相关:
                若相关-----------直接上for
                若无关,再看要素1与要素3是否相同:
                        若相同-----------直接上do…while
                        若不同-----------直接上while

循环可以嵌套,次数越少越好

接收用户输入的值
        Scanner scan = new Scanner(System.in);//新建一个扫描仪,叫scan (名字可以换)
        int(类型可以换) age = scan.nextInt() (同左) ;//接受用户输入的值,赋值给age。

数组 :

(数组类型和八大基本类型不同)
        //动态创建,后期赋值
                int[] (数组类型)  arr(数组名) = new(创建新数组) int[数组的长度/元素个数];
        //静态创建,直接赋值
                int[] arr = {1,4,7};//同上

如何访问:通过(数组名.length)可以获取数组的长度(元素的个数)
        通过下标/索引来引来访问数组中的元素
        遍历,通过for循环来遍历输出
Arrays.toString(数组名)  以数组形式输出数组中的元素,
Arrays.sort(数组名)
        //排序,从小到大排序,然后使用for/toSting输出
        //倒序,从大到小排序,将for(将正序的初始化和条件交换)倒着写,toSting然后输出
System.arraycopy(  a(原数组),  1(从哪个下标开始),  b(目标数组),  0(起始下标),  4(要复制的个数));
        int[ ] b(目标数组) = Arrays.copyOf(  a(原数组),  6(目标数组的长度));
        --->若目标数组长度  >  源数组长度,则末尾补默认值
        --->若目标数组长度  <  源数组长度,则将末尾的截掉

方法

函数、过程
方法的调用:
        无返回值:方法名(有参传参);
        有返回值:数据类型 变量 = 方法名(有参传参);

        (1)封装一段特定的业务逻辑功能
        (2)尽可能的独立,一个方法只干一件事
        (3)方法可以被反复多次调用
        (4)减少代码重复,有利于代码复用(复用性),有利于代码维护

修饰词 返回值类型 方法名(参数列表) {
        方法体------具体的业务逻辑功能实现
        }
public static void(返回值) say( 有/无参 ){
        System.out.println("大家好,我叫WKJ,今年38岁了");
}
有参必须传参,返回的值必须和返回值类型匹配

参数 :


形参:形式参数,定义方法时的参数为形(有类型)参
实参:实际参数,调用方法时的参数为实(有实际值)参

return (返回的值,或者数)

return 值;  //1)结束方法的执行 2)返回结果给调用方-------用在有返回值方法中
return;      //1)结束方法的执行-----------------------------------用在无返回值的方法中

如有缺漏:后续再补· · · · · ·

二、面向对象


类、对象 (每天一个新对象)


        类  >  对象

类中可以包含:

        成员变量 ------------------对象的属性/特征
        类型 变量名;
        方法 -----------------------对象的行为/动作
        void  方法名(){
        }
调用方法:可以在一个类中调(写在main方法中调)
        可以在两个类中调(同上)
        先在main方法中new一个新对象,然后 · · · · · ·如下

数据类型     引用类型变量     指向      对象
Student            zs         =       new    Student();

方法的重载(overload/overloading)  ----------更加方便用户的访问
        (1)发生在同一类中,方法名相同,参数列表不同
        (2)编译器在编译时会根据方法的签名自动绑定方法
        void show(){}
        void show(String name){}
        void show(int age){}
        void show(String name,int age){}
        void show(int age,String name){}
        //int show(){ return 1;} //编译错误,重载与返回值类型无关
        //void show(String address){} //编译错误,重载与参数名称无关

构造方法


        构造函数、构造器、构建器---------复用给成员变量赋初值代码
        构造方法名和类名相同 (需要参传参/成员变量){
        this.成员变量名-------------访问成员变量
        不传参时,可以直接赋值
        传参时,可以赋值。在new对象时输入的参数不使用
        }

        null:空(引用的值为空)      NullPointerException:空指针异常
                补充  
                1.成员变量和局部变量是可以同名的:
                ----使用的时候默认采取就近原则
                ----若想访问成员变量,则this不能省略


内存管理

由JVM来管理的
        (1)堆:new出来的对象(包括成员变量)
                包括引用数组类型,数组名后存地址名,指向数组第一个元素
                第一个元素未存值,为null,存值后,指向存数据的地址
        (2)栈:局部变量(包括方法的参数)
        (3)方法区:存 . class字节码文件(包括静态变量、所有方法)
成员变量:写在类中,方法外--------有默认值
局部变量:方法中------------------------没有默认值
数组也是一个对象,所以数组对象也存储在堆中,
        将数组的元素当作成员变量一并存储在堆中

引用 “数组” 类型 :

与基本类型数组的区别:
       (1)给数组元素赋值必须new一下
       (2)若想访问对象数据必须通过数组元素打点

数据类型    引用类型变量      指向       对象
Student           zs       =          new     Student();
定义数组类型    数组名      赋值                  数组长度 
Student[]             stus  =    new         Student[给数组的长度];

访问: 打点
        数组名.[数组下标]


继承 :

(通过extends来实现继承)
----> 作用:代码复用,少写代码,省事,管理方便
----> 超类/父类:共有的属性和行为
----> 派生类/子类:特有的属性和行为
----> 派生类既能访问自己的,也能访问超类,但是超类不能访问派生类的   “ 超类  >  子类 ”
----> 一个超类可以有多个派生类,一个派生类只能有一个超类---------为单继承 != 多继承
----> 具有传递性
----> java规定:构造派生类之前必须先构造超类
----> 在派生类的构造方法中若没有调用超类的构造方法,则默认super()调用超类的无参构造方法
----> 在派生类的构造方法中若自己调用了超类的构造方法,则不再默认提供
----> super()调用超类构造方法,必须位于派生类构造方法的第1行

继承:父类中的私有对象可以通过get 和 set 方法,来实现在子类中访问

super:指代当前对象的超类对象   ( 父类的属性和方法 )
        super用法:
                1.super.成员变量名     ----> 访问超类的成员变量
                2.super.方法名()          ----> 调用超类的方法
                3.super(有参传参)       ----> 调用超类的构造方法

向上造型


        (1)超类型的引用指向派生类的对象
        (2)能点出什么,看引用的类型------------规定

        引用类型    变量名字      new       对象
       Aoo(超类)        o3   =       new       Boo();(子类)

方法重写


        (1)发生在父子类中,方法名相同,参数列表相同
        (2)重写方法被调用时,看对象的类型------规定

        (1)两同:
                方法名相同
                参数列表相同
        (2)两小:
                派生类方法的返回值类型小于或等于超类方法的
                void和基本类型时,必须相等
                引用类型时,小于或等于
                派生类方法抛出的异常小于或等于超类方法的-------------API
        (3)一大:
                派生类方法的访问权限大于或等于超类方法的

        class 餐馆{
                void 做餐() {  做中餐  }
        }
--1) 我还是想做中餐----------------不需要重写
        class Aoo extends 餐馆{
        }
--2) 我想改做西餐------------------需要重写
        class Aoo extends 餐馆{
                void 做餐() {  做西餐  }  ----->//方法的重写
        }
--3) 我想在中餐之上加入西餐---------需要重写(先super中餐,再加入西餐)
        class Aoo extends 餐馆{
                void 做餐() { super.做餐(); + 做西餐 }  ------>//方法的重写
        }
-----重载和重写的区别-----
        重写(override):发生在父子类中,方法名相同,参数列表相同
        重载(overload):发生在同一类中,方法名相同,参数列表不同


package和import

        (1)package:声明包
                避免类的命名冲突
                同包中的类不能同名,但不同包中的类可以同名
                类的全称:包名.类名
                包名常常用层次结构,建议所有字母都小写
        (2)import:导入类
                同包中的类可以直接访问
                不同包中的类不能直接访问,若想访问:
                先import声明类,再访问类------建议
                类的全称(在调用时写全称)---太繁琐,不建议

访问控制修饰符:-----------保证数据的安全


        public:公开的,任何类
        private:私有的,本类
        protected:受保护的,本类、派生类、同包类
        默认的:什么也不写,本类、同包类

  说明  
        - 类的访问权限只能是public或默认的
        - 类中成员的访问权限如上4种都可以
        - 访问权限由高到低依次为:public>protected>默认的>private
     (如下)
        public int a;    //任何类
        protected int b; //本类、派生类(可以跨包继承)、同包类
        int c;           //本类、同包类
        private int d;   //本类

final

最终的,不可改变的(写在谁的前面,谁就不能改变.可以固定值,方法,类) -------单独应用几率极低
        (1)修饰变量:变量不能被改变
        (2)修饰方法:方法不能被重写
        (3)修饰类:类不能被继承


static:静态的


        1.静态变量:(只有一个值,如果第一次赋值,那么第二次使用时,将在第一次基础上再次进行运算)
                (1)由static修饰
                (2)属于类,存储在方法区中,只有一份
                (3)怎么用: 常常通过类名点来访问
                (4)何时用:所有对象所共享的数据(图片、音频、视频等)

        2.静态方法:

              (1)由static修饰
              (2)属于类,存储在方法区中,只有一份
              (3)怎么用: 常常通过类名点来访问
              (4)静态方法中没有隐式this传递,不能直接访问实例成员
              (5)何时用:方法的操作与对象无关

静态块 :

              (1)由static修饰
              (2)属于类,在类被加载期间自动执行,一个类只被加载一次,所以静态块只执行一次
              (3)何时用:加载/初始化静态资源(图片、音频、视频等)   

                        //在项目中要用到时,可以将图片音频视频放在静态块中,减少内存

  补充  :-------------------------------
        1. 数据(成员变量)私有化(private),行为(方法)大部分公开化(public)
        2. 成员变量分两种:
                1.实例变量:没有static修饰,属于对象的,存储在堆中,有几个对象就有几份
                通过引用(对象)点来访问
                2.静态变量:由static修饰,属于类的,存储在方法区中,只有一份
                通过类名点来访问
        3. 内存管理:由JVM来管理
                1.堆:new出来的对象(包括实例变量)
                2.栈:局部变量(包括方法的参数)
                3.方法区:.class字节码文件(包括静态变量、所有方法)
        4. 图片存储位置:点项目名称submarine                                                                                                                         右键New一个Directory,命名为img,将8张图片复制进去

static final 常量 :


        1.必须声明同时初始化
        2.类名点来访问,不能被改变
        3.建议:常量名所有字母都大写,多个单词用 _ (下划线)隔开
        4.编译器在编译时会将常量直接替换为具体的数,效率高
        5.何时用:数据永不变,并且经常使用(一些固定的值,窗口的高,宽)

abstract 抽象

abstract 抽象方法 (就是一个空壳子,等着其他方法来调用重写)
        1.由abstrsct修饰
        2.只有方法的定义,没有具体的实现(连 {} 都没有)

abstract 抽象类:
        1.由abstract修饰
        2.包含抽象方法的类必须是抽象类
        3.抽象类不能被实例化(new对象)
        4.抽象类是需要被继承的,
                派生类:
                        1.重写所有抽象方法-----变不完整为完整
                        2.也声明为抽象类-------一般不这么用
        5.抽象类的意义:
                1.封装共有的属性和行为------------代码复用
                2.为所有派生类提供统一的类型-----向上造型
                3.  可以包含抽象方法,为所有派生类提供统一的入口(能点出来)
                派生类的行为不同,但是入口是一致的,同时相当于定义了一个标准(强制重写)
  补充  :--------------------
        1.设计规则:
                1.将共有的属性和行为,抽到超类中--------抽共性
                2.若对象的行为都一样,设计为普通方法
                   若对象的方法不一样,设计为抽象方法
          (超类放共有属性和方法,接口放部分共有的属性和方法,独有的属性和方法放到自己的类里面)
                接口是继承的单根性的扩展------实现多继承
                3.接口
                        将部分派生类所共有的属性和行为,抽到接口中
                        接口是对继承的单根性的扩展--------实现多继承

        2.抽象方法/抽象类的疑问:
                1.抽象方法存在的意义是什么?
                        保证当发生向上造型时,通过超类的引用能点出来那个方法
                2.既然意义只在于能点出来什么,那为什么不设计普通方法呢?
                        若设计为普通方法,则派生类可以重写也可以不重写,而设计为抽象方法,                                          可以强制派生类必须重写--------> 做了个标准,强制必须重写


成员内部类 : 应用率低 -----> 了解


    1.类中套类,外面的称为外部类,里面的称为内部类
    2.内部类通常只服务于外部类,对外不具备可见性
    3.内部类对象通常在外部类中创建
    4.内部类中可以直接访问外部类的成员(包括私有的)
       内部类中有个隐式的引用指向了创建它的外部类对象: 外部类名 . this . 


匿名内部类 : -----> 大大简化代码


    1.若想创建一个类(派生类)的对象,并且对象只被创建一次,可以做成匿名内部类
    2.在匿名内部类中默认外面的变量为final的---规定
    3.面试题: 问:内部类有独立的 . class 文件吗     答 : 有

接口


    1.是一种引用数据类型
    2.由interface定义 由public 修饰
    3.只能包含常量和抽象方法
    4.接口不能被实例化(new 对象)
    5.接口是需要被实现(继承的) ,实现派生类: ---必须重写所有抽象方法
    6.一个类可以实现多个接口,用逗号分割,若要继承又要实现,应先继承后实现
    7.接口可以继承接口

    接口中有用default修饰的方法,可以写方法体
    interface Inter{
        default void A(){
                System.out.println("这是default方法");
        }
     }
  接口的关系
        1.类和类---------继承extends
        2.接口和接口----继承extends
        3.类和接口-------实现implements
  接口的意义
        1.实现多继承
        2.制定了一套标准.规则


多态


        1.意义
                1.同一类型的引用指向不同的对象时,有不同的实现-----所有的抽象方法都是多态的
                --------行为的多态 : cut() , getlmage() , move()
                2.同一对象被造型为不同的类型时,有不同的功能----所有的对象都是多态的
                --------对象的多态 : 我 ,你 ,水
        2.向上造型/自动类型转换
                1.超类型的引用指向派生类的对象
                2.能点出来什么,看引用的类型
                3.能造型成为的数据类型有 : 超类+所实现的接口
        3.强制类型转换, 成功的条件只有如下两种
                1.引用所指向的对象,就是该类型
                2.引用所指向的对象,实现了该接口或继承了该类
           如果强转,要先实例化(new) ,再进行强转
        4.强转时若不符合如上条件,则会发生ClassCastException类型转换异常
                建议在强转之前先通过instanceof判断引用的对象是否是该类型


内存管理:由JVM来管理的


        1.堆
                1.存储new 出来的对象(包括实例变量)
        2.垃圾:没有任何引用指向的对象
                  垃圾回收器(GC)不定时到内存中清扫垃圾,回收过程是透明的(看不到的)
                  不一定一发现垃圾就立刻回收,通过调用System.gc() 可以建议JVM尽快调度GC回收
        3.实例变量的声明周期
                创建(new) 对象时储存在堆中,对象被回收时一并被回收
        4.内存泄漏: 不再使用的对象没有被及时的回收,严重的泄漏会导致系统的崩溃
                建议: 不再使用的对象应及时将引用设置为null
        2.栈
                1.存储正在调用的方法中的局部变量(包括方法的参数)
                2.调用方法时,会在栈中为该方法分配一块相应的栈帧,栈帧中存储局部变                                             (包括方法的参数),方法调用结束时,栈帧会自动被清除,局部变量一并被清除
        3.局部变量的生命周期
                调用方法时存储在栈中,方法调用结束时与栈帧一并被清除
        4.方法区
                1.存储 .class 字节码文件(包括静态变量, 所有方法)

面向对象的总结

三大特征

        1.封装:

                1.类: 封装的是对象的属性和行为

                2.方法: 封装的是具体的业务逻辑功能实现

                3.访问控制修饰符: 封装的是具体的访问权限,以保护数据的安全

        2.继承
                作用:代码复用
                超类:所有派生类所共有的属性和行为
                接口:部分派生类所共有的属性和行为
                派生类:派生类所特有的属性和行为
                单一继承、多接口实现,具有传递性
        3.多态:
                行为多态:所有抽象方法都是多态的(通过方法的重写实现的)
                对象多态:所有对象都是多态的(通过向上造型来实现)
                向上造型、强制类型转换、instanceof判断
        4.String:字符串类型

                java.lang.String使用final修饰,不能被继承
                java中的String在内存中采用Unicode编码方式,任何一个字符占用两个字节的编码
                字符串底层封装的是一个字符数组
                字符串一旦创建,对象内容永远无法改变,但字符串引用可以重新赋值------不变对象


常量池:

        1.java对字符串有一个优化措施:字符串常量池(堆中)
        2.java推荐我们使用字面量/直接量的方式来创建字符串,并且会缓存所有以字面量形式创建的字符串对象到常量池中,当使用相同字面量再创建对象时将复用常量池中的对象以减少内存开销,从而避免内存中堆积大量内容相同的字符串对象

二进制

什么是2进制

        1.逢二进一的计数规则

        2.如何将2进制转换为10进制?

                将一个2进制数每个1位置的权值累加即可

        3.java所有的变量\常量存储的都是2进制数!

        4.代码演示

/*
1.java在编译期间将10进制数编译为2进制数,按2进制来运算
    .java(50) 编译后 .class(110010)
2.Integer.toBinaryString()可以将底层的2进制数显示出来
3.int类型是32位2进制数,显示2进制数时自动省略高位0
4.System.out.println()将2进制转换为10进制输出
*/
int n = 50; //110010
System.out.println(Integer.toBinaryString(n)); //2进制
n++; //110011
System.out.println(n); //10进制
System.out.println(Integer.toBinaryString(n)); //2进制

什么是16进制

        1.逢16进1的计数规则

        2.因为2进制的书写太繁琐麻烦

                所以常常用16进制来缩写2进制数字

        3.怎么缩写

                将2进制从最低位开始,每4位2进制缩写为1位16进制

        4.代码演示

/*
    16进制:缩写2进制
    1)0x是16进制字面量前缀,0x开头则编译器按照16进制编译
    2)Java 7提供了2进制字面量前缀 0b----不用,一般都用16进制
*/
int n = 0x4f057afe; //0x表示16进制
int m = 0b1001111000001010111101011111110; //0b表示二进制
System.out.println(Integer.toBinaryString(n)); //按2进制输出
System.out.println(Integer.toBinaryString(m)); //按2进制输出
//结论:用16进制来表示2进制更方便

/*
    8进制:
    1)逢8进1的计数规则
    2)前缀0表示为8进制
    3)数字:0,1,2,3,4,5,6,7,没有7以上的数字
*/
//----小面试题(8进制平时不用)
//权     64 8 1
int x =  067; //0开头表示8进制
System.out.println(x); //十进制的55(6个8加上7个1)

补码

        1.计算机中处理有符号数(正负数)的一种编码方式,java中的补码最小类型时int,32位数

        2.以4位2进制数为例讲解补码的编码规则

                1.计算的时候如果超出4位数就自动溢出舍弃,保持4位数不变

                2.将4位2进制数分一半作为负数使用

                3.最高位称为符号位,高位为1是负数,高位为0是正数

int n = -3;
System.out.println(Integer.toBinaryString(n));

/*
规律数:
1)0111为4位补码的最大值,规律是1个0和3个1,可以推导出:
  32位补码的最大值,是1个0和31个1-----(011111111...)
2)1000为4位补码的最小值,规律是1个1和3个0,可以推导出:
  32位补码的最小值,是1个1和31个0-----(100000000...)
3)1111为4位补码的-1,规律是4个1,可以推导出:
  32位补码的-1是,是32个1------------(11111111...)
*/    
int max = 2147483647; //int的最大值
int min = -2147483648; //int的最小值
System.out.println(Integer.toBinaryString(max)); //011111...
System.out.println(Integer.toBinaryString(min)); //100000...
System.out.println(Integer.toBinaryString(-1)); //11111...

        3.深入理解负值

                1.记住-1的编码是32个1

                2.用-1减去0位置对应的权值

11111111111111111111111111111111 = -1
11111111111111111111111111111101 = -1-2 = -3
11111111111111111111111111111001 = -1-2-4 = -7
11111111111111111111111110010111 = -1-8-32-64 = -105

        4.互补对称

                1.公式:-n=~n+1 结论:一个数的补码=这个数取反+1

                2.举例:

int n = -3;
int m = ~n+1;
System.out.println(m); //3  -3的补码就是-3取反+1

                3.面试题

System.out.println(~100+1); 上述代码的运算结果是(C)  注:求100的补码
A. -98  B.-99 C.-100 D.-101
System.out.println(~-100+1); 上述代码的运算结果是(C)  注:求-100的补码
A.98  B.99  C.100  D.101

位运算

~ 取反
& 与运算
| 或运算
>>> 右移位运算
<< 左移位运算

&  与运算

        1.基本规则:有0则0

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

        2.运算的时候将两个数字对齐,将对应位进行与运算

权                       8421
          6   1    4   f    7   b    b   b
n  =      01100001 01001111 01111011 10111011
m  =      00000000 00000000 00000000 11111111  0xff
k  = n&m  00000000 00000000 00000000 10111011

        上述代码用途

                1.将n的最后8位拆分出来,存储到k中

                2.m数称为掩码,8个1称为8位掩码

                3.上述运算称为:掩码运算

        代码

int n = 0x614f7bbb;
int m = 0xff; //掩码
int k = n & m; //将n的最后8位数拆分出来,存储到k中
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));

|  运算

        1.基本规则:有1则1

        

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

        2.运算的时候将两个数位对齐,对应的位进行或运算

权                       8421
n  =      00000000 00000000 00000000 10111001   0xb9
m  =      00000000 00000000 10111101 00000000   0xbd00
k  = n|m  00000000 00000000 10111101 10111001

        如上案例的意义:错位合并

        代码:

int n = 0xb9;
int m = 0xbd00;
int k = n | m; //将n与m错位合并
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));

>>> 右移位运算

        1.基本规则:将2进制数整体向右移动,低位自动溢出舍弃,高位补0

权                      8421
           6   7    9   f    1   d    9   8
n =        01100111 10011111 00011101 10011000
m = n>>>1  001100111 10011111 00011101 1001100
k = n>>>2  0001100111 10011111 00011101 100110
g = n>>>8  00000000 01100111 10011111 00011101

        2.代码

int n = 0x679f1d98;
int m = n>>>1;
int k = n>>>2;
int g = n>>>8;
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));
System.out.println(Integer.toBinaryString(g));

<<  左移位运算

        1.基本规则

权                        8421
             5   e    4   e    0   d    e   e
n =          01011110 01001110 00001101 11101110
m = n<<1     1011110 01001110 00001101 111011100
k = n<<2     011110 01001110 00001101 1110111000

        2.代码

int n = 0x5e4e0dee;  
int m = n<<1;
int k = n<<2;
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));

移位运算的数学意义

权    64  32  16  8  4  2  1
                  0  1  0  1 = 5      向左移动
              0   1  0  1    = 10
          0   1   0  1       = 20
      0   1   0   1          = 40

左移位代码:自行编码验证

int n = 5;
System.out.println(n<<1); //10
System.out.println(n<<2); //20
System.out.println(n<<3); //40

右移位代码:自行编码验证

int n = 100;
System.out.println(n>>>1); //?
System.out.println(n>>>2); //?
System.out.println(n>>>3); //?

你可能感兴趣的:(java-ee)