运算符
2.4 运算符
2.4.1 算术运算符
包括+、-、*、/、%、++、--.
注意
byte类型和short类型运算时会自动提升为int类型
Input
byte b1 = 3;
byte b2 = 5;
byte sum = b1 + b2;
System.out.println(sum);Output
Application.java:5: 错误: 不兼容的类型: 从int转换到byte可能会有损失
byte sum = b1 + b2;
^
1 个错误- 同一类型参与运算,结果的类型与参与运算的类型一致
- 若运算中有大类型参与运算,结果为大类型
- 绝大部分小数转换为二进制是无限小数,所以double类型无法精确存储小数,也不能进行精确运算
Input
double d1 = 3;
double d2 = 2.98;
System.out.println(d1 - d2);Output
0.020000000000000018- 整数/0
ArithmeticException;任意非0数字/0.0 输出Infinite;0/0.0输出NaN
Input
int i = 1;
System.out.println(i / 0);Output
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Application.main(Application.java:4)Input
int i = 1;
System.out.println(i / 0.0);Output
InfinityInput
int i = 1;
System.out.println(i / -0.0);Output
-InfinityInput
int i = 0;
System.out.println(i / -0.0);Output
NaN- 取模运算,先按正数取余,再看左运算位符号判定结果符号
Input
System.out.println(3.2 % 2);Output
1.2Input
System.out.println(5.4 % 1.7);Output
0.3000000000000005- 小数可以当做取模运算的操作数
++/--运算在变量名之前,表示先自增,自增完成之后才会参与运算。在之后则先拿原值参与运算,之后再自增
Input
int i = 5;
int j = i++;取出i中的5 → i自增 → 将5赋值给j
Input
int i = 5;
int j = i++ * 2;
System.out.println("i = " + i);
System.out.println("j = " + j);Output
i = 6
j = 10取出i中的5 → 5和2相乘得10 → i自增 → 将10赋值给j
Input
int i = 5;
int j = ++i * 2;
System.out.println("i = " + i);
System.out.println("j = " + j);Output
i = 6
j = 12取出i中的5 → i自增(6) → 将6和2相乘得12 → 将12赋值给j
Input
int i = 3;
int j = i++ + ++i;
System.out.println("i = " + i);
System.out.println("j = " + j);Output
i = 5
j = 8取出i中的3 → i自增(4) → i自增(5) → 3+5得8 → 将8赋值给j
Input
int i = 3;
int j = ++i + i++;
System.out.println("i = " + i);
System.out.println("j = " + j);Output
i = 5
j = 8取出i中的3 → i自增(4) → i自增(5) → 将4和自增前的4相加得8 → 将8赋值给j
byte和short类型可以参与++/--运算,运算结束后保持原类型(底层进行了强制转换)
2.4.2 赋值运算符
包括=、+=、-=、*=、/=、%=、|=、&=、^=、<<=、>>=和>>>=.
注意
- 除
=以外,其余赋值运算符要求变量必须有值 byte/short类型可以参与赋值运算
Bonus
判断以下魔法程序的输出值
- Inputjava
int i = 5; System.out.println(i += i -= i *= 5); - Inputjava
int i = 3; System.out.println(i += i *= i -= i++); - Inputjava
int i = 5; System.out.println(i += i -= i *= i++); - Inputjava
int i = 5; System.out.println(i += i -= i *= i++ + ++i);
Output
-155 + (5 - (5 * 5)) = -15Output
3int i = 3;i += i *= i -= i++;3 + (3 * (3 - 3)) = 3Output
-155 + (5 - (5 * 5)) = -15Output
-505 + (5 - (5 * (5 + 7))) = -50
2.4.3 关系运算符
或称“比较运算符”
包括>、<、>=、<=、==、!=
2.4.4 逻辑运算符
或称“条件运算符”
包括&&、||、!、&、|、^和?:
特别的
- 运算符
?:是一个三目运算符
语句result = someCondition ? value1 : value2;表示:
“如果某条件为真,则将值1赋给结果,否则将值2赋给结果”The Conditional Operators
...
Another conditional operator is?:, which can be thought of as shorthand for anif-then-elsestatement (discussed in the Control Flow Statements section of this lesson). This operator is also known as the ternary operator because it uses three operands. In the following example, this operator should be read as: "IfsomeConditionistrue, assign the value ofvalue1to result. Otherwise, assign the value ofvalue2to result."
...
原文 - 运算符
&&和||具有短路效果
2.4.5 位运算符
包括&、|、^、~、<<、>>和>>>
关于 & | ^
我们可以注意到,在逻辑运算符和位运算符中都出现了&、|、^.
在官方文档的表述中,&、|、^三个运算符属于位运算符,而不是逻辑运算符,但在实践中我们发现两种具体情形下 JVM 都可以正确理解当前上下文这三个运算符的含义。故本文将三个运算符分别写进了两个分类。
Input
byte b1 = 0b0010101;
byte b2 = 0b1010101;
System.out.println(Integer.toBinaryString(b1 & b2));
boolean bb1 = true;
boolean bb2 = false;
System.out.println(bb1 & bb2);Output
10101
false注意
位运算针对的是整数,运算的是数据的补码
2.4.6 类型比较运算符
运算符instanceof用来判断对象是否为类的实例
Input
System.out.println("abc" instanceof String);Output
true2.4.7 优先级
自上而下优先级逐渐递减。 
特别的
运算符()、[]和.虽不在表中,但享有最高的优先级。