12.字节码的初步认识,来自i=i++,i=++i原理分析

Sherwin.Wei Lv7

首先来代码:

1
2
3
4
5
6
7
public class TestPlusPlus {
public static void main(String[] args) {
int i = 0;
i++;
System.err.println(i);
}
}

然后执行 javap -c TestPlusPlus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TestPlusPlus {
public TestPlusPlus();
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 //把int型常量0push到栈中,即当前栈顶的值为1
1: istore_1 //pop栈顶的1给变量i。赋值操作(i=0)
2: iinc 1, 1 //自增指令。变量i的值加0,执行完成后,i的值为1
5: getstatic #2 // Field java/lang/System.err:Ljava/io/PrintStream;
8: iload_1
9: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
12: return
}

然后改造下代码:

1
2
3
4
5
6
7
public class TestPlusPlus {
public static void main(String[] args) {
int i = 0;
i = i++;
System.err.println(i);
}
}

执行 javap -c TestPlusPlus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TestPlusPlus {
public TestPlusPlus();
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 //push局部变量i的值0入栈,即当前栈顶的值为0
3: iinc 1, 1 //自增指令。变量i的值加1,执行完成后,i的值为1
6: istore_1 //pop栈顶的0赋给变量i。即变量i存放的值1被栈顶的元素覆盖,变为0
7: getstatic #2 // Field java/lang/System.err:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: return
}

再次改变代码:

1
2
3
4
5
6
7
public class TestPlusPlus {
public static void main(String[] args) {
int i = 0;
i = ++i;
System.err.println(i);
}
}

执行javap -c TestPlusPlus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TestPlusPlus {
public TestPlusPlus();
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: iinc 1, 1 //自增指令。变量i的值加1,执行完成后,i的值为1
5: iload_1 //push局部变量i的值1入栈,即当前栈顶的值为1
6: istore_1 //pop栈顶的1赋给变量i.
7: getstatic #2 // Field java/lang/System.err:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: return
}

主要关注iinc 1, 1和 iload_1和istore_1.

Comments
On this page
12.字节码的初步认识,来自i=i++,i=++i原理分析