我尝试了以下代码:
class Converter{
public static void main(String args[]) {
byte num = 1;
num = num * 2.5; // line 1
System.out.println("Result is : "+num);
}
}
所以编译器抛出错误:
error: incompatible types: possible lossy conversion from double to the byte at line 1
稍后,我用简写操作符= *:
更改了第1行 class Converter{
public static void main(String args[]) {
byte num = 1;
num *= 2.5;
System.out.println("Result is : "+num);
}
}
使用输出编译并成功运行:
Result is:2
我能否知道简写操作符在JAVA中的工作方式不同。为什么会这样呢?
答案 0 :(得分:9)
从JLS compound assigment operator文档中,您可以看到以下示例:
例如,以下代码是正确的:
short x = 3;
x += 4.6;
并导致x的值为7,因为它相当于:
short x = 3;
x = (short)(x + 4.6);
默认情况下,它只是自动转换结果。
PS:在这个other answer中,我试图解释你需要使用JLS强制执行以下操作的原因
short x = 3;
x = x + 1; //Won't compile
它非常新,所以我愿意在那里提出建议。
答案 1 :(得分:1)
正如AxelH已经说的那样,它是一个compound assignement,但我想对此进行描述:
E1 op= E2
形式的复合赋值表达式是等效的 到E1 = (T) ((E1) op (E2))
,其中T
是E1
的类型,E1
除外 仅评估一次。
这意味着根据定义它会投射结果。例如:
byte b = 1;
b *= 2.3;
System.out.println(b); // prints 2
来自您的评论:
不,你不能。它不会抑制任何错误,因为在转换中没有错误(在此上下文中)。所以我可以说速记运算符可以抑制有损转换 错误,只是做了什么输入?
答案 2 :(得分:1)
形式E1 op = E2的复合赋值表达式是等价的 到E1 =(T)((E1)op(E2)),其中T是E1的类型,除了E1 仅评估一次。
编译后你可以看到你的例子的字节码(检查"15.26.2. Compound Assignment Operators" 3-10)。
3: i2d //convert an int into a double
4: ldc2_w #2 // double 2.5d
7: dmul //multiply two doubles
8: d2i // convert a double to an int
9: i2b //convert an int into a byte
10: istore_1 //store int value into variable 1