第三章:操作符

一、操作符简介

  1. 操作符接受一个或多个参数,并生成一个新值。
  2. 操作目标:几乎所有的操作符都只能操作“基本类型”。有些操作符能改变操作数自身的值,被称为“副作用”,如自增符和自减符。例外的操作符是“=”、“==”、“!=”,这些操作符能操作所有的对象。String类支持“+”和“+=”。
  3. 优先级:括号 优先于 * / 优先于 + -
  4. 赋值:取右边的值把它复制给左边。右值可以是常量、表达式(只要它能生成一个值)。

为对象“赋值”时引起的“别名问题”,代码示例如下:

Person p1=new Person();
Person p2=new Person();
p1=p2;

将将p2复制给p1,那么原先p1引用所指的对象将被垃圾回收器回收。p1和p2
引用都指向原先p2所指向的Person对象。

二、各种操作符

1. 算术操作符

(1) 包括+ - * /以及%。
(2) 同时进行运算和赋值如:+=。

2. 自增和自减符

(1) 包括 ++ 和 --。
(2) 前缀:先运算再生成值,后缀:先生成值再运算。
(3) 副作用操作符:唯一的副作用操作符,能改变操作数自身的值,而不仅仅是使用。

3. 关系操作符

(1) 包括< > <= >= == !=。
(2) 关系操作符能生成一个boolean类型结果。如果关系真实生成true,否则为false。
(3) 关系操作符操作对象引用时注意,即使两个引用所指的两个对象内容一样,但是这两个引用是不同的(引用存储了对象的地址),故下述代码输出结果为false。

Integer n1=new Integer(11);
Integer n2=new Integer(11);
System.out.println(n1==n2);

如果需要比较两个对象的内容,需要使用equals()方法(注意需要重写)。

4. 逻辑运算符

(1) 包括与(&& )、或(||)、非(!)。
(2) 这些操作符的操作参数都只能是布尔类型的。
(3) 逻辑操作符的生成结果也是一个布尔类型的值。

短路现象:如exp1 && exp2 && exp3,如果exp1为假,那么exp2和exp3将不再计算;还例如exp1 || exp2 || exp3,如果exp1为真,那么exp2和exp3将不再计算。

5. 按位操作符

(1) 包括按位与(&)、按位或(|)、按位异或(^)、按位非(~)。
(2) 运算规则如下:
& :两个输入位两个是1,则生成1;否则生成0。
| :两个输入位只要有一个是1,则生成1;两个输入位都是0才会生成0。
^ :两个输入位有一个是1,但不全是1,则生成1,否则生成0。
~ :输入1生成0,输入0生成1。
(3) 按位操作符可以与等号(=)联合使用。但其中~不行,因为它是一元运算符。

6. 移位操作符

(1) 有符号左移和右移<< >>,无符号右移>>>。
a、 左移运算符
  左移运算符<<使指定值的所有位都左移规定的次数。
  1)它的通用格式如下所示:
  value << num
  num 指定要移位值value 移动的位数。
  左移的规则只记住一点:丢弃最高位,0补最低位。
  如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了332=1位。
  2)运算规则
  按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
  当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃;
  当左移的运算数是long 类型时,每移动1位它的第63位就要被移出并且丢弃。
  当左移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。
  3)数学意义
  在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。
  4)计算过程:
  例如:3 <<2(3为int型)
  1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,
  2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,
  3)在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,
  转换为十进制是12。
  移动的位数超过了该类型的最大位数,
  如果移进高阶位(31或63位),那么该值将变为负值。

b、右移运算符
  右移运算符<<使指定值的所有位都右移规定的次数。
  1)它的通用格式如下所示:
  value >> num
  num 指定要移位值value 移动的位数。
  右移的规则只记住一点:符号位不变,左边补上符号位。
  2)运算规则:
  按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。
  当右移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。
  例如,如果要移走的值为负数,每一次右移都在左边补1,如果要移走的值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位)(sign extension ),在进行右移。
  操作时用来保持负数的符号。
  3)数学意义
  右移一位相当于除2,右移n位相当于除以2的n次方。
  4)计算过程
  11 >>2(11为int型)
  1)11的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011。
  2)把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。
  3)最终结果是0000 0000 0000 0000 0000 0000 0000 0010。
  转换为十进制是2。
  35 >> 2(35为int型)
  35转换为二进制:0000 0000 0000 0000 0000 0000 0010 0011。
  把低位的最后两个数字移出:0000 0000 0000 0000 0000 0000 0000。 1000
  转换为十进制: 8
  5)在右移时不保留符号的出来
  右移后的值与0x0f进行按位与运算,这样可以舍弃任何的符号位扩展,以便得到的值可以作为定义数组的下标,从而得到对应数组元素代表的十六进制字符。

c、无符号右移运算符>>>
  它的通用格式如下所示:
  value >>> num
  num 指定要移位值value 移动的位数。
  无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位。
  无符号右移规则和右移运算是一样的,只是填充时不管左边的数字是正是负都用0来填充,无符号右移运算只针对负数计算,因为对于正数来说这种运算没有意义。
  无符号右移运算符>>> 只是对32位和64位的值有意义。

  对了 位移运算符 依旧可以 组合使用 例如 : <<= >>= <<+ >>+ >>>= .............. 等等

7. 三元操作符

(1) 形式:boolexp ? val1 :val2,当boolexp为真时计算val1,为假时计算val2。
(2) 优点:简洁;
缺点:可读性差。

8. 逗号运算符

(1) 仅仅用在for循环中
(2) 形式:for(int i=1,j=i*10;i<10;i++,j+=2)

9. 字符串操作符 + 和 +=

(1) 操作符重载。
(2) 当编译器观察到String后面跟着一个非String时会尝试将其转换为String。
(3) 编译器会自动将双引号内的字符序列转换为String。

String s="A";
int a=1,b=2,c=3;
System.out.println(s+a+b+c);
System.out.println(s+(a+b+c));//先计算a+b+c=6,再将6转换为字符串6连接到s之后
System.out.println(x+" "+s);//将先导变量x转换为String类型
System.out.println(""+x);//效果等同于Integer.toString(x)

输出为:
A123
A6
1 A

10. 类型转换操作符

(1) 基本类型“等级”划分
byte(1) short(2) char(2) <--- int(4) <--- long(8) float(4) <--- double(8)
(2) 强制类型转换:由高到低时人为操作。
(3) 自动类型转换:由低到高,可以人为操作使代码更为清晰可读。

11. 直接常量

(1) 有时候我们使用的直接常量编译器会产生误解,所以我们需要进行适当的引导。
(2) 直接常量的后缀 L表示long类型,D表示double类型,F表示float类型;0X前缀表示十六进制数,后面跟0-9以及A-F(或者a-f)。

posted @ 2020-11-17 13:31  leiyangace  阅读(160)  评论(0)    收藏  举报