第三章 操作符
3.1 更简单的打印语句
3.2 使用Java操作符
操作符
接受一个或多个参数,并生成新的值。
操作数
操作符的参数。
几乎所有的操作符都只能操作基本数据类型。
例外:=、==和!=,这三个操作符可以操作所有对象。而’+’和’+=’可以操作String对象。
3.3 优先级
最简单的就是以括号明确规定计算顺序。
3.4 赋值
只能是=右边的值赋值给=左边的值,因此常数不能作为左值(e.g. 4 = a)。
基本数据类型
a = 4;
b = a;
上述过程中,a和b都是基本数据类型,b = a就是将a的内容复制给b。如果对a进行修改,不会对b造成影响。
引用类型
class Tank{
int level;
}
public class Assignment{
Tank t1 = new Tank();
Tank t2 = new Tank();
t1.level = 9;
t2.level = 47;
System.out.println("t1.level:" + t1.level);
System.out.println("t2.level:" + t2.level);
t1 = t2;
System.out.println("t1.level:" + t1.level);
System.out.println("t2.level:" + t2.level);
t2.level = 27;
System.out.println("t1.level:" + t1.level);
System.out.println("t2.level:" + t2.level);
}
在上述代码中,t1 = t2本质上其实与基本数据类型类似,将t2的内容复制给了t1,只不过t2的内容是一个内存地址,它指向了一个Tank对象,因此赋值完成后,t1和t2都指向了同一个Tank对象,之后又对该Tank对象的level进行了修改,但是t1和t2都指向了同一个Tank对象,只是对象自身的字段值发生了变化而已。
3.5 算术操作符
+ - * / %
注意/是所谓的地板除, n / m = q,即n = q * m + r(0 <= r < q)。
+=
x += 4; // x = x + 4;
-=同理。
3.6 自动递增和递减
++和–
a = 1;
System.out.println(a);
System.out.println(++a); //前缀式递增(pre-increment),先递增后使用
System.out.println(a++); //后缀式递增(post-increment),先使用后递增
–同理。
3.7 关系操作符
>、<、>=、<=、==和!=,只有两种结果:true和false。
3.8 逻辑操作符
&&(与)、||(或)和!(非),只可以应用于boolean类型的值。
短路
expr1 && expr2;// expr1为false时,不进入expr2,即短路
expr1 & expr2;//无论expr1为true还是false,都进入expr2
expr1 || expr2;// expr1为true时,不进入expr2,即短路
expr1 | expr2;//无论expr1为true还是false,都进入expr2
3.9 直接常量
直接常量后的后缀字符标识了它的类型。
long n1 = 200L; //long类型常在数字后加L,不建议加l,因为与1太像
float f1 = 0.2f; //float类型必须在数字后加f或者F,否则就是double类型,编译会报错
double d1 = 0.1d; //double类型可在数字后加d或者D,但一般不用加
不同进制的数字
int i1 = 0x2f; //十六进制小写
int i2 = 0X2F; //十六进制大写
int i3 = 0177; //八进制由前缀0和后续的0~7的数字表示
科学计数法
float expFloat = 1.33e-43f;
expFloat = 1.33E-43f;
3.10 按位操作符
按位操作符会对两个二进制数中的对应位进行布尔代数运算,并最终生成一个结果。
按位与
1&1 = 1,1&0 = 0,0&1 = 0,0&0 = 0;
按位或
1|1 = 1;1|0 = 1,0|1 = 1,0|0 = 0;
按位异或
1^1 = 0,1^0 = 1,0^1 = 1,0^0 = 0;
取反
~1 = 0,~0 = 1;
按位与、按位或和按位异或可与”=”联用,即&=、|=以及^=。
3.11 移位操作符
移位操作符的运算对象是二进制整数的位。
左移位操作符<<:按照操作符右侧指定的位数将操作符左边的操作数向左移动,在低位补0;
有符号右移操作符>>:按操作符右侧指定的位数将操作符左边的操作数向右移动,若左边的操作数为正,则在高位补0;若左边的操作数为负,则在高位补1。
无符号右移操作符>>>:按操作符右侧指定的位数将操作数左边的操作数向右移动,无论左边的操作数为正还是为负,都在高位补0。
char/byte/short/int类型的数值在做移位运算时,都会向转换为int类型,然后再做移位运算,所得结果为int类型。
long类型数值在做移位运算时,所得结果为long类型。
移位操作符可以与”=”联用,但是要注意的是,当对byte/short类型使用>>=时,会先将byte/short类型数值转换成int类型数值,再做移位运算,所得结果为int类型,最后做截取,转换为byte/short类型,因此不一定能得到正确的结果。
short s = -1;
s >>>= 10;
System.out.println(Integer.toBinaryString(s));
byte b = -1;
System.out.println(Integer.toBinaryString(b));
3.12 三元操作符 if-else
boolean-exp为true,取值为value0;boolean-exp为false,取值为value1。
boolean-exp ? value0 : value1;
3.13 字符串操作符 +和+=
3.14 使用操作符时常犯的错误
相等与赋值操作;
3.15 类型转换操作符
类型转化(cast):在适当时候,Java会将一种数据类型自动转换为一种类型。
窄化转换(narrowing conversion):将容纳更多信息的类型转换成无法容纳那么多信息的类型,可能会造成信息的丢失,必须显式地进行。
扩展转换(widening conversion):将容纳较少信息的类型转换成容纳信息较多的类型,无需显式进行。
byte < short < int < long < float < double;
3.16 Java没有sizeof
3.17 操作符小结
注意int类型的范围,如果对两个足够大的int值执行乘法运算,结果就会溢出。
public class Overflow {
public static void main(String[] args){
int big = Integer.MAX_VALUE;
System.out.println("big = " + big);
int bigger = big * 4;
System.out.println("bigger = " + bigger);
}
}
在这一过程中,编译器不会报错,运行时也不会有异常。