第三章:操作符
一、操作符简介
- 操作符接受一个或多个参数,并生成一个新值。
- 操作目标:几乎所有的操作符都只能操作“基本类型”。有些操作符能改变操作数自身的值,被称为“副作用”,如自增符和自减符。例外的操作符是“=”、“==”、“!=”,这些操作符能操作所有的对象。String类支持“+”和“+=”。
- 优先级:括号 优先于 * / 优先于 + -
- 赋值:取右边的值把它复制给左边。右值可以是常量、表达式(只要它能生成一个值)。
为对象“赋值”时引起的“别名问题”,代码示例如下:
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)。

浙公网安备 33010602011771号