Puzzle 09: Tweedledum

复合运算符的问题

下面两个表达式等价吗?

x += i;

x = x + i;

答: 否.

事实上有一个例子可以式第一句合法, 第二句非法, 要做到这一点, 只需声明:

short x = 0;

int i = 123456;

JLS 15.26.2中有对应的描述. E1 op= E2E1 = (T) ((E1) op (E2)) 等价, TE1的类型.

如果右边的类型比左边宽, 运算的时候可能会发生窄化转型(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.

  1. JLS 5.1.3 Narrowing Primitive Conversions
  2. JLS 15.26 Assignment Operators