a C*_*CVn 8 java variable-assignment compound-operator
我发现Java的+ =, - =,*=,/ =复合赋值运算符(好问题:)),但它有一部分我不太明白.借用这个问题:
Run Code Online (Sandbox Code Playgroud)int i = 5; long l = 8;然后
i = i + l;将不会编译但i += l;将编译正常.
联系问题的接受答案表明:
形式E1 op = E2的复合赋值表达式等效于E1 =(T)((E1)op(E2)),其中T是E1的类型,除了E1仅被评估一次.
这给出i += l;了与仅评估一次i = (int)((i) + (l));的异常相同的内容i.
A long可能(IIRC甚至保证)长于a int,因此可以保持更大范围的值.
鉴于这种情况很容易导致数据丢失,因为在执行语句(r值表达式评估或赋值)期间的某些时刻必须缩小转换,为什么i += l;不是编译时错误或至少是警告?
Ern*_*ill 14
基本上,因为i += l编译好像是编写的i = (int) (i + l).向int值byte和char变量添加值时有类似的"惊喜" - 赋值运算符有效,而普通加法运算符则不然.
鉴于这种情况很容易导致数据丢失,因为在执行语句(r值表达式评估或赋值)期间的某些时刻必须缩小转换,为什么i + = l; 不是编译时错误或至少是警告?
正如您所说,它可能应该是编译时错误或至少是警告.我所知道的大多数书籍和教程x += y;都是速记的x = x + y;.老实说,我不知道在第15.26.2节中除了一个JLS的化合物分配操作员之外的任何区别.
在Java Puzzlers的第2章(谜题9):陷阱,陷阱和角落案例中,作者(Joshua Bloch和Neal Gafter)要求您提供声明x并且i这是一个法律声明:
x += i;
Run Code Online (Sandbox Code Playgroud)
这不是:
x = x + i;
Run Code Online (Sandbox Code Playgroud)
有很多解决方案,包括您在问题中发布的前两行代码.作者警告不要使用复合赋值运算符的类型的变量byte,short和char,并建议使用的类型的变量,这些运营商的时候int,你应该确保在RHS表达式不是long,float或double.
他们总结了以下观点(强调我的):
总之,复合赋值运算符以静默方式生成强制转换.如果计算结果的类型比变量的类型宽,则生成的转换是危险的缩小转换.这样的演员可以默默地丢弃精确度或幅度. 对于语言设计者来说,复合赋值运算符生成隐形强制转换可能是一个错误.复合赋值,其中变量的类型比计算结果的类型更窄应该是非法的.
| 归档时间: |
|
| 查看次数: |
1468 次 |
| 最近记录: |