< p>
a += 10
和a = a + 10
是完全相同的吗?还是它们之间存在差异?我在学习Java作业时遇到了这个问题。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
的复合赋值表达式相当于E1 = (T)((E1) op (E2))
,其中T
是E1
的类型,除了E1
仅被计算一次。
有趣的是,规范中给出的例子:
short x = 3;
x += 4.6;
byte +(byte, byte)
运算符。请参阅 http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2。 - Jon Skeet没有区别,两者是缩写。甚至编译器会为它们生成相同的指令。
编辑:正如我刚发现的那样,编译器并不会为两者生成相同的代码。查看下面的内容:
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与iinc的区别。编辑2:指令规范大致如下:iadd-将堆栈上的两个int相加;iinc-将局部变量增加一个常数。正如我们上面所看到的,只要右侧有一个常数,我们可以使用iinc节省几个指令。但是如果我们有a + = a呢?那么代码看起来像这样: 7: iload_1
8: iload_1
9: iadd
10: istore_1
如果我们有 a = a + a
,那么它与我们得到的相同。
Test.java
? :) - Pascal Thivent换句话说,在你的情况下,区别在于隐式类型转换:形如 E1 op= E2 的复合赋值表达式等同于 E1 = (T)((E1) op (E2)),其中 T 是 E1 的类型,除了 E1 只被计算一次。
byte a = 100;
a += 1000; // compiles
a = a + 1000; // doesn't compile, because an int cannot be assigned to a byte.
byte a = 100; a += 1000;
这段代码会给 a
赋什么值? - Jerry Jeremiah在你展示的表达式中,它们是等价的,在像下面这样的表达式中:
array[getIndex(context)][some / complex + expression] += offset;
在一些情况下,使用+=(以及其他赋值运算符)能够帮助你更好地实现想法。如果表达式比较复杂,使用+=运算符可以避免错误并提高可读性和可维护性。