java中a + = 10和a = a + 10之间的区别?
a += 10
和a = a + 10
都是一样的,还是有一些区别呢? 我在学习Java中的任务时遇到了这个问题。
正如你现在提到的铸造…这种情况有所不同:
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= E2
的复合赋值expression式相当于E1 = (T)((E1) op (E2))
,其中T
是E1
的types,只是E1
只被计算一次。
有趣的是,他们在规范中给出的例子是:
short x = 3; x += 4.6;
在Java中是有效的,但不在 C#中…基本上在C#中,编译器执行+ =和 – =的特殊shell以确保expression式是目标types或是目标types范围内的文字。
没有区别,一个是另一个的简写。 即使编译器也会为两者生成相同的指令。
编辑 :编译器不会为这两个生成相同的代码,因为我刚刚发现。 看一下这个:
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初学者,或者任何不担心在最小级别上进行优化的人来说,都是可以互换的。 长的答案将取决于我阅读关于iadd vs iinc。
编辑2 :好的,我回来了。 指令规格(大致)如下:
iadd – 添加堆栈中的前两个整数
iinc – 通过常量递增局部variables
正如我们上面看到的,只要右边有一个常量,我们可以使用iinc保存一些指令。
但是如果有的话会发生什么
a += a
?
然后代码如下所示:
7: iload_1 8: iload_1 9: iadd 10: istore_1
如果我们有a = a + a
,这也是我们得到a = a + a
。
这在Java语言规范第15.25.2节中定义 。 显着的部分是:
E1 op = E2的复合赋值expression式相当于E1 =(T)((E1)op(E2)),其中T是E1的types,只是E1只被计算一次。
也就是说,你的情况不同的是隐式types转换:
byte a = 100; a += 1000; // compiles a = a + 1000; // doesn't compile, because an int cannot be assigned to a byte.
在你expression的expression式中,它们是相等的,expression式如下:
array[getIndex(context)][some / complex + expression] += offset;
你会明白在哪些情况下+ =运算符(和其他赋值运算符)是有用的。 如果expression式不重要,那么+ =操作符可以防止错误,并提高可读性和可维护性。
在S / W领域有一些术语,我可以向你解释一下,
在a=a+1
分配a
是在两步后测量的
- 系统计算一个值(在这里创build一个新的独立副本)
- 系统将10添加到隔离variables
a
然后隔离a
的值被分配到左侧a
但在第二种情况下,
- 系统知道a的值,并直接将10添加到a(这里没有独立的副本)。
希望这对你有帮助,还有一件事,我们通常使用的方法是a += 10;
因为它降低了操作成本,