1. i++和++i的基本概念
案例 1:
/**
* @author pcwl
* @description i++ 和 ++i 详解
*/
public class Test {
public static void main(String[] args) {
int i= 1;
int j = i++;
System.out.println("j = " + j);
System.out.println("i = " + i);
}
}
public class Test {
public static void main(String[] args) {
int i= 1;
int j = ++i;
System.out.println("j = " + j);
System.out.println("i = " + i);
}
}
int i = 1;
int j = i++; // 先将i的原始值(1)赋值给变量j(1),然后i变量的值加1
int j = ++i; // 先将i变量的值加1,然后将i的当前值(2)赋值给变量j(2)
2. i++ 和 ++i 的实现原理
/**
* @author pcwl
* @description i++ 和 ++i 详解
*/
public class Test {
public void testIPlus() {
int i = 0;
int j = i++;
}
public void testPlusI() {
int i = 0;
int j = ++i;
}
}
...
{
...
public void testIPlus();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=1
0: iconst_0 // 生成整数0
1: istore_1 // 将整数0赋值给1号存储单元(即变量i)
2: iload_1 // 将1号存储单元的值加载到数据栈(此时 i=0,栈顶值为0)
3: iinc 1, 1 // 1号存储单元的值+1(此时 i=1)
6: istore_2 // 将数据栈顶的值(0)取出来赋值给2号存储单元(即变量j,此时i=1,j=0)
7: return // 返回时:i=1,j=0
LineNumberTable:
line 4: 0
line 5: 2
line 6: 7
public void testPlusI();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=1
0: iconst_0 // 生成整数0
1: istore_1 // 将整数0赋值给1号存储单元(即变量i)
2: iinc 1, 1 // 1号存储单元的值+1(此时 i=1)
5: iload_1 // 将1号存储单元的值加载到数据栈(此时 i=1,栈顶值为1)
6: istore_2 // 将数据栈顶的值(1)取出来赋值给2号存储单元(即变量j,此时i=1,j=1)
7: return // 返回时:i=1,j=1
LineNumberTable:
line 9: 0
line 10: 2
line 11: 7
}
...
3. i++ 和 ++i 使用的一些坑
01
案例1:i=i++导致的结果异常
public class Test {
public static void main(String[] args) {
int i = 0;
i = i++;
System.out.println("i = " + i); // 0
}
}
正常来讲,执行的结果应该是:i = 1,实际结果却是:i = 0,这多少会让人有些诧异。为什么会出现这种情况呢?我们来从编码后的代码中找答案。上面的代码编译后的核心代码如下:
0: iconst_0 // 生成整数0
1: istore_1 // 将整数0赋值给1号存储单元(即变量i,i=0)
2: iload_1 // 将1号存储单元的值加载到数据栈(此时 i=0,栈顶值为0)
3: iinc 1, 1 // 1号存储单元的值+1(此时 i=1)
6: istore_1 // 将数据栈顶的值(0)取出来赋值给1号存储单元(即变量i,此时i=0)
7: getstatic #16 // 下面是打印到控制台指令
10: new #22
13: dup
14: ldc #24
16: invokespecial #26
19: iload_1
20: invokevirtual #29
23: invokevirtual #33
26: invokevirtual #37
29: return
temp = i;
i = i + 1;
i = temp;
所以 i 不变, 依然是0。
02
案例2
public class Test {
public static void main(String[] args) {
int i = 0;
i++;
System.out.println("i = " + i); // 1
}
}
0: iconst_0 // 生成整数0
1: istore_1 // 将整数0赋值给1号存储单元(即变量i,i=0)
2: iinc 1, 1 // 1号存储单元的值+1(此时 i=1)
5: getstatic #2
8: new #3
11: dup
12: invokespecial #4
15: ldc #5
17: invokevirtual #6
20: iload_1
21: invokevirtual #7
24: invokevirtual #8
27: invokevirtual #9
30: return
-------- END ---------

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。关注公众号并回复 888 领取,更多内容陆续奉上