《Java架构筑基》从Java基础讲起——Java运算符

1. 有哪些运算符

Java提供了丰富的运算符,能够将之分为四种:算术运算符、位运算符、关系运算符、逻辑运算符ide

2. 算术运算符

算术运算符的操做对象必须是数值类型,不能为boolean类型使用算术运算符,可是能够为char类型使用算术运算符。由于在Java中,char类型在本质上是int的子集。 |运算符|含义| |:--:|:--:| |+|加法(也是一元加号)| |-|减法(也是一元减号)| ||乘法| |/|除法| |%|求模| |++|自增| |- -|自减| |+=|加并赋值| |-=|减并赋值| |=|乘并赋值| |/=|除并赋值| |%=|求模并赋值|编码

3. 位运算符

Java定义了几个位运算符,可用于整数类型——long,int,short,char和byte。 |运算符|含义| |:--:|:--:| |~|按位一元取反| |&|按位与| |||按位或| |^|按位异或| |>>|右移| |>>>|右移零填充| |<<|左移| |&=|按位与并赋值| | |= |按位或并赋值| |^=|按位异或并赋值| |>>=|右移并赋值| |>>>=|右移零填充并赋值| |<<=|左移并赋值|code

在Java中,全部整数类型都由宽度可变的二进制数字表示,除char类型外都是有符号整数,这意味着它们便可表示正数,也能够表示负数。对象

Java中使用“2的补码”进行编码,即负数的表示方法为:首先反转数值中的全部位(1变为0,0变为1),而后再将结果加1。例如,-42的表示方法为:经过反转42中的全部位(00101010),获得11010101,而后再加1,获得11010110,即-42。 为了解码负数,首先反转全部位,而后加1。例如,反转-42(11010110),获得00101001,即41,再加一则获得42。it

3.1 位逻辑运算符

位逻辑运算符包括&、|、^和~。class

  • 运算规则以下表所示 |A|B|A|B|A&B|A^B|~A |:--:|:--:|:--:|:--:|:--:|:--:| |0|0|0|0|0|1| |1|0|1|0|1|0| |0|1|1|0|1|1| |1|1|1|1|0|0|

3.2 左移

左移运算符“<<”能够将数值中的全部位向左移动指定的次数,格式为:扩展

value << num
  • num指定了将value中的值向左移动的次数,对于高阶位,每次左移都被移出并丢失,右边的位用0补充。这意味着左移int类型操做数时,若是某些位一旦超出31位,那么这些位将丢失。若是操做数是long类型,那么超出位63的位会丢失。
  • 当左移byte和short型数据时,Java的自动类型提高会致使意外的结果。当对表达式进行求值时,byte和short型数值会被提高为int类型,且表达式的结果也是int型。
  • 这意味着对byte和short型数值进行左移操做的结果为int型,若移动的位数不超出位31,则移动的位不会丢失。此外,当将负的byte和short型数值提高为int型时,会进行符号扩展,所以高阶位将使用1填充。
  • 例如,若是左移byte型数值,会先将该数值提高为int型,而后左移。这意味着若是想要的结果是移位后的byte型数值,就必须丢弃结果的前三个字节,能够经过将结果强制转换为byte类型来完成位数截取。

举个例子:二进制

public static void main(String[] args) {
    public static void main(String[] args) {
        //0011 1100
        byte a = 60;
        // a首先被提高为int类型,即(0000 0000 0000 0000 0000 0000 0011 1100)
        // 左移两位,结果为(0000 0000 0000 0000 0000 0000 1111 0000),即240
        int i = a << 2;
        // 先左移两位,结果为(0000 0000 0000 0000 0000 0011 1100 0000)
        // 舍弃前三个字节,获得(1100 0000),即-64
        byte b = (byte) (i << 2);
        System.out.println("i等于:" + i);
        System.out.println("b等于:" + b);
    }
}

输出结果是:方法

i等于:240
b等于:-64

由于每次左移都至关于将原始值乘2,因此能够将之做为乘法的搞笑替代方法。可是若是将二进制1移进高阶位,结果将会变成负数。数据

3.3 右移

右移的规则与左移相似,实例代码以下:

public static void main(String[] args) {
    //0011 1100
    byte a = 60;  
    // a首先被提高为int类型,即(0000 0000 0000 0000 0000 0000 0011 1100)
    // 右移两位,结果为(0000 0000 0000 0000 0000 0000 0000 1111),即15
    int i = a >> 2;
    // 先右移两位,结果为(0000 0000 0000 0000 0000 0000 0000 0011)
    // 舍弃前三个字节,获得(0000 0011),即3
    byte b = (byte) (i >> 2);
    System.out.println("i等于:" + i);
    System.out.println("b等于:" + b);
}

执行结果

i等于:15
b等于:3

每次右移一位,至关于将该值除以2,并舍弃全部余数。能够利用这一特性实现高效的除法操做。

  • 当进行右移操做时,右移后的顶部(最左边)位使用右移前顶部为使用的值填充,这称为符号扩展。当对负数进行右移操做时,该特性能够保留负数的符号。
    public static void main(String[] args) {
    byte a=(byte) 0b11111000;
    System.out.println("a等于:"+a);
    int b=a>>1;
    System.out.println("b等于:"+b);
    }

    执行结果

    a等于:-8
    b等于:-4

3.4 无符号右移

每次移位时,“>>”运算符自动使用原来的内容填充高阶位,这个特性能够保持数值的正负性。可是,有时候对那些非数值的内容进行移位操做,并不关心高阶位初始值是多少,只但愿用0来填充高阶位,这就是无符号右移。

  • 为了完成无符号右移,须要使用Java的无符号右移运算符“>>>”,该运算符老是将0移进高阶位。
    public static void main(String[] args) {
    //二进制表示(11111111 11111111 11111111 11111111)
    int a=-1;
    System.out.println(a);
    //右移二十四位(00000000 00000000 00000000 11111111)
    a=a>>>24;
    //输出结果是 255
    System.out.println(a); 
    }

4. 关系运算符

关系运算符用于断定一个操做数与另外一个操做数之间的关系。 |运算符|结果| |:--:|:--:| |==|等于| |!=|不等于| |>|大于| |<|小于| |>=|大于等于| |<=|小于等于|

5. 逻辑运算符

关系运算符用于断定一个操做数与另外一个操做数之间的关系。 |运算符|结果| |:--:|:--:| |&|逻辑与| |||逻辑或| |^|逻辑异或| ||||短路或| |&&|短路与| |!|逻辑一元非| |&=|逻辑与并赋值| ||=|逻辑或并赋值| |^=|逻辑异或并赋值| |==|等于| |!=|不等于| |?:|三元运算符|

相关文章
相关标签/搜索