在Java中,当你执行以下操作时:
int b = 0;
b = b + 1.0;
你会得到一个可能的精度损失错误。但是如果你这样做,为什么会发生这种情况呢?
int b = 0;
b += 1.0;
没有错误吗?
在Java中,当你执行以下操作时:
int b = 0;
b = b + 1.0;
你会得到一个可能的精度损失错误。但是如果你这样做,为什么会发生这种情况呢?
int b = 0;
b += 1.0;
没有错误吗?
这是因为b += 1.0;
等同于b = (int) ((b) + (1.0));
。缩小原始类型转换(JLS 5.1.3)隐藏在复合赋值操作中。
这也解释了为什么以下代码可以编译:A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
For example, the following code is correct:
short x = 3; x += 4.6;
and results in
x
having the value7
because it is equivalent to:short x = 3; x = (short)(x + 4.6);
byte b = 1;
int x = 5;
b += x; // compiles fine!
byte b = 1;
int x = 5;
b = b + x; // DOESN'T COMPILE!
byte b = 1;
int x = 5;
b = (byte) (b + x); // now it compiles fine!
x += i;
只是x = x + i;
的简写。这并不完全正确:如果结果的类型比变量的类型更宽,复合赋值运算符将执行一个隐式的窄化原始类型转换。byte
、short
或char
的变量上使用复合赋值运算符。当在类型为int
的变量上使用复合赋值运算符时,请确保右侧的表达式不是类型long
、float
或double
。当在类型为float
的变量上使用复合赋值运算符时,请确保右侧的表达式不是类型double
。这些规则足以防止编译器生成危险的窄化转换。值得注意的是最后一段:在这方面,C# 更加严格(参见 C# 语言规范 7.13.2 复合赋值)。
op=
运算符在Java中都被称为“复合赋值”。但是,我确实认为在大多数搜索引擎中查询符号而不是关键字很困难。 - polygenelubricants