问题:给出一个对变量x和i的声明,使得下面这条语句合法:
x += i;
但是下面这条不合法:
x = x + i;
许多人会认为第一个表达式只是第二个表达式的简写方式。这并不准确。这两个表达式都被称为赋值表达式。第二个表达式使用的是简单赋值操作符,而第一个表达式使用的是复合赋值操作符。
换句话说,复合赋值操作符自动的将所执行的计算的结果转型为其左侧变量的类型。如果结果的类型于改变量的类型相同,那么这个转型不会造成任何影响。然而,如果结果的类型比该变量的类型要宽,那么复合赋值操作符将悄悄地执行一个窄化原生类型转换。因此,我们有很好的理由解释为什么尝试着执行等价的简单赋值可能会产生一个编译错误。
为了更具体的说明,并给这个谜题提供一个解决方案,假设我们在该谜题的两个赋值表达式之前有下面的这些声明:
short x = 0;
int i = 123456;
复合赋值编译将不会产生任何错误:
x += i;
你可能期望x的值在这条语句执行之后是123456,但是并非如此,它的值是-7616。int类型的数值123456对于short来说太大。自动产生的转型悄悄地吧int数值的高两位截掉了。
相应的简单赋值是非法的,因为它试图将int数值赋值给short变量,而这需要显示的转型:
x = x + i;
这应该是明显的,复合赋值表达式可能是危险的。为了避免这种错误,请不要将复合赋值操作符作用于byte,short或char类型的变量。在将复合赋值操作符作用于int变量上,要确保右侧的不是long、float或double类型。在将复合赋值操作符作用于float类型的变量上时候,要确保表达式右侧不是double类型。