JAVA中的速记运算符给出了两种不同的结果

时间:2017-05-09 06:28:45

标签: java operators

我尝试了以下代码:

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中的工作方式不同。为什么会这样呢?

3 个答案:

答案 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)),其中TE1的类型,E1除外   仅评估一次。

这意味着根据定义它会投射结果。例如:

byte b = 1;
b *= 2.3;
System.out.println(b); // prints 2

来自您的评论:

  

所以我可以说速记运算符可以抑制有损转换   错误,只是做了什么输入?

不,你不能。它不会抑制任何错误,因为在转换中没有错误(在此上下文中)。

答案 2 :(得分:1)

根据java语言规范enter image description here

  

形式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

instruction