Java中的+= 10和a = a + 10之间的区别?

2022-09-01 10:27:40

是和两者相同,还是它们之间存在一些差异?我在学习Java作业时得到了这个问题。a += 10a = a + 10


答案 1

正如你现在提到的选角...在这种情况下有一个区别:

byte a = 5;
a += 10; // Valid
a = a + 10; // Invalid, as the expression "a + 10" is of type int

来自 Java 语言规范 15.26.2 节

该形式的复合赋值表达式等价于 ,其中 是 的类型,只计算一次。E1 op= E2E1 = (T)((E1) op (E2))TE1E1

有趣的是,他们在规范中给出的例子:

short x = 3;
x += 4.6;

在 Java 中有效,但在 C#中无效...基本上,在 C# 中,编译器执行 += 和 -= 的特殊大小写,以确保表达式是目标类型,或者是目标类型范围内的文本。


答案 2

没有区别,一个是另一个的简写。甚至编译器也会为两者生成相同的指令。

编辑:编译器不会为两者生成相同的代码,正如我刚刚发现的那样。看看这个:

dan$ cat Test.java
public class Test {
    public static void main(String[] args) {
        int a = 0;
        a = a + 10;
        a += 20;
    }
}

dan$ javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   bipush  10
   5:   iadd
   6:   istore_1
   7:   iinc    1, 20
   10:  return

}

因此,简短的答案,特别是对于Java初学者或任何不担心在最小级别进行优化的人来说,它们是可以互换的。长答案将取决于我阅读有关iad vs iinc的信息。

编辑2:好的,我回来了。指令规格(大致)如下:

iadd - 在堆栈上添加前两个整数

iinc - 将局部变量递增一个常量

正如我们在上面看到的,只要右侧有一个常量,我们就可以使用iinc保存几条指令。

但是,如果我们有

a += a?

然后代码如下所示:

   7:   iload_1
   8:   iload_1
   9:   iadd
   10:  istore_1

如果我们有,这是同样的东西。a = a + a