两者是否相同a += 10
,a = a + 10
或者它们之间有什么区别?我在学习 Java 作业时遇到了这个问题。
5 回答
正如您现在提到的铸造......在这种情况下有所不同:
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;
在 Java 中有效,但在C# 中无效...基本上在 C# 中,编译器执行 += 和 -= 的特殊情况,以确保表达式是目标类型或者是目标类型范围内的文字。
没有区别,一个是另一个的简写。甚至编译器也会为两者生成相同的指令。
编辑:编译器不会为两者生成相同的代码,正如我刚刚发现的那样。看一下这个:
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
.
这在Java 语言规范第 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.
在您显示的表达式中,它们是等价的,例如:
array[getIndex(context)][some / complex + expression] += offset;
您会了解 += 运算符(和其他赋值运算符)在哪些情况下有用。如果表达式不平凡,则 += 运算符可以防止错误并提高可读性,从而提高可维护性。
S/W领域有一些术语,我可以给你解释一下,
in a=a+1
assignment fora
是在两个步骤后测量的
- 系统计算 a 的值(这里创建一个新的隔离副本)
- 系统将孤立变量加10,
a
然后将孤立的值a
分配给左侧a
但在第二种情况下,
- 系统知道 a 的值,
a
直接加 10(这里没有单独复制)。
希望这对您有所帮助,还有一件事,我们通常使用的方法是a += 10;
因为它降低了运营成本,就像其他人一样,