在Java中,+运算符会导致参与操作的变量自动提升为其中最大宽度的类型。
比如:
- short+int,会导致short自动提升为int再相加,变成int+int。
- int+String,会导致int自动提升为String再相加,变成String+String。
对于复合运算符来说,也是如此,且看下面一个死循环:
public static void main(String[] args) {
short i = -1;
System.out.println(Integer.toBinaryString(i)); // 展示short拓宽int后的二进制值
while (i != 0) {
// Java的数值运算低于int的,会先提升到int来计算
// 先拓宽
// 1111111111111111 = 》 11111111111111111111111111111111
// 无符号右移
// 01111111111111111111111111111111
// 窄化
// 01111111111111111111111111111111 = 》 1111111111111111
// 原因:不会产生任何变化;Java窄化int为short,将直接截掉高16位,又回到起点
i >>>= 1; // 复合运算符导致了short自动拓宽
System.out.println(Integer.toBinaryString(i));
}
}
总结:不要在short、byte或char类型上使用复合赋值运算符,避免自动拓宽为int再参与计算导致的bug。