Talk is cheap , show me your code!
欢迎来到付振南Java博客,让我们一起学习Java吧!

关于自增变量的一道面试题 int i = 1;i=i++结果是多少?

关于自增变量的一道面试题

int i = 1 ; i = i++;
像这种自增变量的题目相信大家碰到的时候一定很酸爽,理解的人怎么做都不会错,不理解的人做多少题都答不对,今天给大家带来最透彻的讲解。

题目

/**
 * 自增变量
 * @author fuzhennan
 */
public class SelfIncreasingVariable {
    public static void main(String[] args){
        int i = 1;
        i = i ++;
        int j = i++;
        int k = i + ++i * i++;
        System.out.println("i= "+i);
        System.out.println("j= "+j);
        System.out.println("k= "+k);
    }
}

答案

看完题目,相信大家在心中肯定有了自己的答案,这道题的正确答案是:i=4;j=1;k=11.

解题思路

遇到这种题我们需要拿纸和笔,在纸上内存结构图,然后一步一步模拟虚拟机编译的操作就行。

1.首先int i = 1;就是在栈帧的局部变量表中创建一个变量i,初始值为1;

2.然后第二句,i = i ++; 也就是把i++操作压入操作数栈,此时操作数栈里的i的值为1,计算出i++结果为2,然后局部变量表i中的值修改为2,等式右边执行完了,然后需要把等式右边赋值给左边,也就是把操作数栈中i=1的值覆盖掉局部变量表中i的值,所以此时i的值为1;

局部变量表 操作数栈
int i = 1, 2, 1 i=1

3.接下来一句,int j = i ++;这步的操作就是,现在局部变量表中创建一个j变量,然后把i++压入操作数栈,此时操作数栈中i的值仍旧是1,然后执行i++操作,结果为2,然后修改局部变量表中i的值为2,注意此时在局部变量表中i的值已经变成2了,然后把操作数栈中i=1赋值给j,j的值就是1;

局部变量表 操作数栈
int i = 1, 2, 1, 2 i=1
int j =1 i=1

4.接下来就是重难点了,int k = i + ++i * i++;我们一步一步来,首先在局部变量表中创建一个k变量,然后看右边,i+ ++i * i++,从左到右,i+也就是2+,++i压入操作数栈,先++在使用,所以就是2+3,然后修改局部变量表中i的值为3,然后2+3 * i++,把i++压入操作数栈,先使用后++,所以是2 + 3 * 3,然后在局部变量表中修改i的值为4,然后等式右边2 + 3 * 3最终结果是11,所以把11赋值给k。

局部变量表 操作数栈
int i = 1, 2, 1, 2, 3, 4 i=1
int j =1 i=1
int k = 11 2+ 3 * 3

所以最终结果就是i=4, j=1, k=11。

字节码文件

我们来看一下编译后的字节码文件。

我把每一个对应的语句都标注对应了起来,L0里面

ICONST_1  声明一个变量为i
ISTORE 1  i赋值为1

对应的就是int i = 1;

ILOAD 1   将变量i从局部变量表加载到操作数栈
IINC 1 1  自增
ISTORE 1  从操作数栈存储到局部变量表

对应的就是i = i ++;

ILOAD 1   加载
IINC 1 1  自增
ISTORE 2  存回到局部变量表

对应的就是int j = i++;

ILOAD 1  加载
IINC 1 1  先自增
ILOAD 1  再加载
ILOAD 1  先加载
IINC 1 1  再自增
IMUL 计算乘法
IADD  计算加法
ISTORE 3 存回到局部变量表

对应的就是int k = i + ++i * i++;

总结

  1. 赋值=,最后计算;
  2. =右边的从左到右加载值依次压入操作数栈;
  3. 实际先算哪个,看运算符优先级;
  4. 自增自减操作都是直接修改变量值,不经过操作数栈;
  5. 最后的赋值之前,临时结果也是存在操作数栈。
赞(4) 打赏
未经允许不得转载:付振南Java博客 » 关于自增变量的一道面试题

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏