【发布时间】:2011-01-06 02:51:01
【问题描述】:
a += 10 和 a = a + 10 是否相同,或者它们之间有什么区别?我在学习 Java 作业时遇到了这个问题。
【问题讨论】:
-
这个问题重复的问题是在这个问题之后发布的,所以它不应该是这个问题的重复吗?
-
@Kröw 不,这并不重要。参见例如meta.stackoverflow.com/q/251938/2891664。
a += 10 和 a = a + 10 是否相同,或者它们之间有什么区别?我在学习 Java 作业时遇到了这个问题。
【问题讨论】:
S/W领域有一些术语,我可以给你解释一下,
在a=a+1 中,a 的赋值是在两步之后测量的
a加10,然后将隔离a的值分配给左侧a
但在第二种情况下,
a的值,直接给a加10(这里没有做隔离副本)。希望这对您有所帮助,还有一件事,我们通常使用a += 10;的方法,因为它可以降低运营成本,就像其他人一样,
【讨论】:
正如您现在提到的铸造......在这种情况下有所不同:
byte a = 5;
a += 10; // Valid
a = a + 10; // Invalid, as the expression "a + 10" is of type int
来自 Java 语言规范section 15.26.2:
E1 op= E2形式的复合赋值表达式等价于E1 = (T)((E1) op (E2)),其中T是E1的类型,但E1只计算一次。
有趣的是,他们在规范中给出的示例:
short x = 3;
x += 4.6;
在 Java 中有效,但在 C# 中不是...基本上在 C# 中,编译器执行 += 和 -= 的特殊情况,以确保表达式是目标类型或者是目标类型范围内的文字。
【讨论】:
byte +(byte, byte) 运算符。见docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.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 初学者或任何不担心在最小级别进行优化的人来说,它们是可以互换的。长答案将取决于我阅读有关 iadd 与 iinc 的内容。
编辑 2:好的,我回来了。指令规格(大致)如下:
iadd - 添加栈顶的两个整数
iinc - 将局部变量增加一个常量
正如我们在上面看到的,我们可以使用 iinc 保存一些指令,只要右侧有一个常量。
但是如果我们有会发生什么
a += a?
那么代码如下所示:
7: iload_1
8: iload_1
9: iadd
10: istore_1
如果我们有a = a + a,我们会得到同样的结果。
【讨论】:
Test.java? :)
这是在Java Language Specification, section 15.25.2 中定义的。重点是:
复合赋值表达式 形式 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 的值是多少?
在您显示的表达式中,它们是等价的,在如下表达式中:
array[getIndex(context)][some / complex + expression] += offset;
您会知道 += 运算符(和其他赋值运算符)在哪些情况下有用。如果表达式不平凡,则 += 运算符可以防止错误并提高可读性,从而提高可维护性。
【讨论】: