复合赋值操作符包括 +=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、^=和|=,Java 语言规范中讲到,复合赋值 E1 op= E2 等价于简单赋值E1 =(T)((E1)op(E2)),其中T 是E1 的类型,除非E1 只被计算一次。换句话说,复合赋值表达式自动地将它们所执行的计算的结果转型为其左侧变量的类型。
总之,复合赋值操作符会悄悄地产生一个转型。如果计算结果的类型宽于变量的类型,那么所产生的转型就是一个危险的窄化转型。这样的转型可能会悄悄地丢弃掉精度或数量值。对语言设计者来说,也许让复合赋值操作符产生一个不可见的转型本身就是一个错误;对于在复合赋值中的变量类型比计算结果窄的情况,也许应该让其非法才对。
复合赋值操作符要求两个操作数都是原始类型的,例如int,或包装了的原始类型,例如Integer,但是有一个例外:如果在+=操作符左侧的操作数是String类型的,那么它允许右侧的操作数是任意类型,在这种情况下,该操作符执行的是字符串连接操作。简单赋值操作符(=)允许其左侧的是对象引用类型,这就显得要宽松许多了:你可以使用它们来表示任何你想要表示的内容,只要表达式的右侧与左侧的变量是赋值兼容的即可。
Object x = "Buy ";
String i = "Effective Java!";
简单赋值是合法的,因为 x + i 是String 类型的,而String 类型又是与Object赋值兼容的:
x = x + i;
复合赋值是非法的,因为左侧是一个Object 引用类型,而右侧是一个String类型:
x += i;
这个 谜 题对程序 员 来说 几乎 算不上什么 教训 。对 语言设 计 者 来说,加法的 复 合 赋 值操作符应该在 右 侧 是 S trin g 类 型的 情况 下, 允 许 左 侧 是Ob j ect 类 型。这 项修改 将 根 除这个 谜 题所 展 示 的 违背 直 觉 的行为。转载自: 无码团队blog-wuma.koubei.com