Puzzle 09: Tweedledum
复合运算符的问题
复合运算符的问题
下面两个表达式等价吗?
x += i;
x = x + i;
答: 否.
事实上有一个例子可以式第一句合法, 第二句非法, 要做到这一点, 只需声明:
short x = 0;
int i = 123456;
在JLS 15.26.2中有对应的描述. E1 op= E2 和 E1 = (T) ((E1) op (E2)) 等价, T 是 E1的类型.
如果右边的类型比左边宽, 运算的时候可能会发生窄化转型(JLS章节号). 窄化转型就可能导致计算错误, 但是编译环境和运算环境都不会报错的.
所以在使用复合运算符时, 要注意避免右边的操作数类型比左边的宽. 书中说的比较啰嗦, 其实就这么个意思.
文中举了一个错误的实例:
short x = 0;
int i = 123456;
x += i;
System.out.println(x);
它输出的是-7616, 以下是计算过程:
int型123456的二进制补码表示入:
0000 0000 0000 0001 1110 0010 0100 0000
强制转化为short型, 舍弃高16位后成为:
1110 0010 0100 0000
即-7616.
附
- JLS 5.1.3 Narrowing Primitive Conversions
- JLS 15.26 Assignment Operators