懂得i++和++i
Posted huan30
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了懂得i++和++i相关的知识,希望对你有一定的参考价值。
懂得i++和++i
案例
代码1
package org.huangao.other.dome1;
import org.junit.Test;
public class Dome1 {
@Test
public void test1() {
int j = 0;
j = j++;
System.out.println(j);
}
@Test
public void test2() {
int j = 0;
j = ++j;
System.out.println(j);
}
}
结果
test1:0
test2:1
代码2
package org.huangao.other.dome1;
import org.junit.Test;
public class Dome1 {
@Test
public void test1() {
int j = 0;
// j = j++;
j++;
System.out.println(j);
}
@Test
public void test2() {
int j = 0;
// j = ++j;
++j;
System.out.println(j);
}
}
结果
test1:1
test2:1
? 可以初步分析是 j 值 对于 j++ 赋值的地方有所差异
分析
代码1的字节码
D:jdk1.8.0_211injavap.exe -c org.huangao.other.dome1.Dome1
Compiled from "Dome1.java"
public class org.huangao.other.dome1.Dome1 {
public org.huangao.other.dome1.Dome1();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void test1();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: return
public void test2();
Code:
0: iconst_0
1: istore_1
2: iinc 1, 1
5: iload_1
6: istore_1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: return
}
Process finished with exit code 0
分析
? 首先我们先看test1 方法
iconst_0 代表将int型 0 推送至栈顶
istore_1 将栈顶 int 型数值存入第二个本地变量 即 j=0
iload_1 将第二个int 型本地变量 推送至栈顶 即 j=0
iinc 1,1 将局部变量表中1号元素自增1,此时j=1
istore_1 将栈顶 int 型数值存入第二个本地变量
getstatic
iload_1
invokevirtual
return
? 接下来看test2方法
iconst_0 将 int 型 0 推入栈顶
istore_1 将栈顶 int 型 数值存入第二个本地变量
iinc 1,1 将局部变量表1 号元素 自增1 ,此时j=1
iload_1 将第二个 int 型本地变量推送至栈顶
istore_1 将栈顶 int 型数值 存入第二个本地变量
getstatic
.....
结论
本来局部变量表中的j已经完成了自增,但是在进行赋值的时候,是将操作栈中的数据弹出,直接进行覆盖操作
? 如果站在JVM的层次来说 对于 i++ 和 ++i
- i++ 是先被操作数栈拿去了(先执行了load指令),然后再在局部变量表中完成了自增,但是操作数栈中还是自增前的值
- 而++i是在局部变量表中完成了自增(先执行了innc指令),然后再被load进行了操作数栈,所以操作数栈中保存的是自增后的值
课后思考
@Test
public void test3() {
int i = 4;
int b = i++;
int a = ++i;
}
public void test3();
Code:
0: iconst_4
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_2
7: iinc 1, 1
10: iload_1
11: istore_3
12: return
@Test
public void test3() {
int i = 4;
i = i++;
System.out.println(i);
i = ++i;
System.out.println(i);
}
4
5
public void test3();
Code:
0: iconst_4
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: iinc 1, 1
17: iload_1
18: istore_1
19: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
22: iload_1
23: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
26: return
@Test
public void test3() {
int i = 4;
i = ++i;
System.out.println(i);
i = i++;
System.out.println(i);
}
5
5
public void test3();
Code:
0: iconst_4
1: istore_1
2: iinc 1, 1
5: iload_1
6: istore_1
7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
14: iload_1
15: iinc 1, 1
18: istore_1
19: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
22: iload_1
23: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
26: return
以上是关于懂得i++和++i的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段