点击关注公众号,Java干货及时送达

前言

如果只用普通的知识解释i++和++i的话
  • i++ 先将i赋值再++
  • ++i 先++再赋值
但是这简单的回答并不能入吸引面试官的眼球,如果用java字节码指令分析则效果完全不同。

代码实现

publicclassOperandStackTest
{

/**

    程序员面试过程中, 常见的i++和++i 的区别

     */

publicstaticvoidadd()
{

//第1类问题:
int
 i1 = 
10
;

        i1++;

        System.out.println(i1);
//11

int
 i2 = 
10
;

        ++i2;

        System.out.println(i2);
//11

//第2类问题:
int
 i3 = 
10
;

int
 i4 = i3++;

        System.out.println(i3);
//11
        System.out.println(i4);
//10

int
 i5 = 
10
;

int
 i6 = ++i5;

        System.out.println(i5);
//11
        System.out.println(i6);
//11

//第3类问题:
int
 i7 = 
10
;

        i7 = i7++;

        System.out.println(i7);
//10

int
 i8 = 
10
;

        i8 = ++i8;

        System.out.println(i8);
//11

//第4类问题:
int
 i9 = 
10
;

int
 i10 = i9++ + ++i9;
//10+12
        System.out.println(i9);
//12
        System.out.println(i10);
//22
    }


publicstaticvoidmain(String[] args)
{

        add();

    }

}

运行结果

字节码指令

通过javap -v out目录下的class文件名 在终端运行得到如下结果
publicstaticvoidadd()
;

    descriptor: ()V

    flags: ACC_PUBLIC, ACC_STATIC

    Code:

      stack=
2
, locals=
10
, args_size=
0
0
: bipush        
10
2
: istore_0

3
: iinc          
0
1
6
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
9
: iload_0

10
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
13
: bipush        
10
15
: istore_1

16
: iinc          
1
1
19
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
22
: iload_1

23
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
26
: bipush        
10
28
: istore_2

29
: iload_2

30
: iinc          
2
1
33
: istore_3

34
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
37
: iload_2

38
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
41
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
44
: iload_3

45
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
48
: bipush        
10
50
: istore        
4
52
: iinc          
4
1
55
: iload         
4
57
: istore        
5
59
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
62
: iload         
4
64
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
67
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
70
: iload         
5
72
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
75
: bipush        
10
77
: istore        
6
79
: iload         
6
81
: iinc          
6
1
84
: istore        
6
86
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
89
: iload         
6
91
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
94
: bipush        
10
96
: istore        
7
98
: iinc          
7
1
101
: iload         
7
103
: istore        
7
105
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
108
: iload         
7
110
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
113
: bipush        
10
115
: istore        
8
117
: iload         
8
119
: iinc          
8
1
122
: iinc          
8
1
125
: iload         
8
127
: iadd

128
: istore        
9
130
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
133
: iload         
8
135
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
138
: getstatic     #
4// Field java/lang/System.out:Ljava/io/PrintStream;
141
: iload         
9
143
: invokevirtual #
5// Method java/io/PrintStream.println:(I)V
146
return

解释以上运行结果

第一类问题
对应的指令为
先将i1的值为10入栈(bipush),然后将int类型的值从栈中存到局部变量表0的位置,然后执行iinc将0位置的值+1,然后将局部变量表0位置的数入栈执行输出操作
所以i1的值为11
先将i2的值为10入栈(bipush),然后将int类型的值从栈中存到局部变量表1的位置,然后执行iinc将1位置的值+1,然后将局部变量表1位置的数入栈执行输出操作
所以i2的值为11

总结

由于没有赋值操作,区别不大。
第二类问题
先将i3入栈存储到局部变量表2的位置,然后将它入栈,执行iinc将2位置的值加一,i4存储到局部表量表3的位置
所以i3是11,i4还是10
将i5入栈存储到局部变量表4的位置,由于是++i所以先iinc将4位置的值加一,然后将局部变量表4的值入栈,执行赋值操作,所以都是11
第三类问题
先将i7入栈,然后存到局部变量表6的位置,先把i6入栈,然后把6处的值加一,由于又将这个值存储到局部变量表6处,所以产生覆盖又把值变为10。
而++i不会产生覆盖先执行加一然后再把值入栈,在赋值给局部变量表中,所以i8为11。
第四类问题
先将i9=10入栈,然后存在局部变量表8的位置
int i10 = i9++ + ++i9;

先iload将8位置的i9入栈然后执行iinc将8处的i9加一,然后执行++i9,在将8处的i9加一
此时i9=10+1+1为12,然后将8位置的i9入栈,执行add将栈中的两i9相加,得到的值存储到局部变量表9的位置
所以i10=10+12(i9++后还是10,++i9后是12,因为执行了两次iinc操作)
然后调用虚方法和静态方法,在将9处的值入栈执行输出语句
(感谢阅读,希望对你所有帮助)
来源:https://blog.csdn.net/weixin_45706762/
(完)
加我"微信获取一份 最新Java面试题资料
请备注:666不然不通过~
最近好文
最近面试BAT,整理一份面试资料Java面试BAT通关手册,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:关注公众号并回复 java 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡
继续阅读
阅读原文