Aar*_* Fi 5 java post-increment
以下代码打印出"3",而不是"4",如您所料.
public class Foo2 {
public static void main(String[] args) {
int a=1, b=2;
a = b + a++;
System.out.println(a);
}
}
Run Code Online (Sandbox Code Playgroud)
我明白了.在加载"a"的值之后发生后缀增量.(见下文).
我不太明白的是为什么.postfix ++的运算符优先级高于+所以不应该先执行?
% javap -c Foo2
Compiled from "Foo2.java"
public class Foo2 extends java.lang.Object{
public Foo2();
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_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_2
5: iload_1
6: iinc 1, 1
9: iadd
10: istore_1
11: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
14: iload_1
15: invokevirtual #3; //Method java/io/PrintStream.println:(I)V
18: return
Run Code Online (Sandbox Code Playgroud)
Pav*_*aev 20
Postfix ++递增变量的值,并返回增量前的值.因此,operator++您的示例中的返回值将是1,当然1 + 2将给出3,然后将其分配给a.到赋值时,++已经增加了ato 的值2(因为优先级),所以=覆盖递增的值.
Joa*_*uer 13
此处不会忽略运算符优先级.
唯一有点令人困惑的事情a++是后缀++运算符有两个不同的效果:
因此,如果a有1并且b在此行之前具有值2:
a = b + a++;
Run Code Online (Sandbox Code Playgroud)
然后执行以下步骤:
b
b的值为2,所以请记住值2a++
a++的值为1,因此请记住值1a1,因此它现在保持值2a如您所见,代码有效地将两个值分配给a:
a在评估期间分配2a++a作为分配的结果,3被分配由于第二个赋值发生在第一个赋值之后,因此您只能看到第二个赋值的效果,并且您将始终观察到a该行之后的值为3.
编辑:我将尝试提供反编译代码的解释.可能有点难以理解,除非您知道JVM如何在内部工作(即您知道JVM是如何基于堆栈的VM以及这意味着什么):
// Push the constant 1 on the stack
0: iconst_1
// Pop the topmost value from the stack (1) and store it in the local variable #1 (a.k.a "a")
1: istore_1
// Push the constant 2 on the stack
2: iconst_2
// Pop the topmost value from the stack (2) and store it in the local variable #2 (a.k.a "b")
3: istore_2
// Load the local variable #2 ("b") and push its value (2) on the stack
4: iload_2
// Load the local variable #1 ("a") and push its value (1) on the stack
5: iload_1
// Increment the local variable #1 by 1 (this action does not use the stack!)
6: iinc 1, 1
// Pop the 2 topmost values from the stack (2 and 1), add them and push the result (3) back on the stack
9: iadd
// Pop the topmost value from the stack (3) and store it in local variable #1 ("a")
10: istore_1
Run Code Online (Sandbox Code Playgroud)
第0-4行简单地实现
int a=1, b=2;
Run Code Online (Sandbox Code Playgroud)
第4-10行实现
a = b + a++;
Run Code Online (Sandbox Code Playgroud)
我已经遗漏了其他几行,因为没有任何有趣的事情发生了.
作为一个有趣的旁注:很明显,这段代码根本没有优化.原因是优化是Java世界中运行时环境(即JVM)的任务,而不是编译器(javac例如).