Java面试题错题

错题一 i的值输出是多少

/**
 * @program: JVMDemo
 * @description: test
 * @author: 郑朝文
 * @create: 2021-08-20 11:59
 **/
public class ErrorTest {
    public static void main(String[] args) {
        ErrorTest inc = new ErrorTest();
        int i = 0;
        inc.fermin(i);
        i= i ++;
        System.out.println(i);
    }

    public void fermin(int i) {
        i++;
    }
}

解析 根据字节码指令来进行分析
Java虚拟机栈(JVM Stack)描述的是Java方法执行的内存模型,而JVM内存模型是基于“栈帧”的,每个栈帧中都有 局部变量表 和 操作数栈 (还有动态链接、return address等),那么JVM是如何执行这个语句的呢?通过javap大致可以将上面的两行代码翻译成如下的JVM指令执行代码。

 0 new #2 <com/yi/ErrorTest>
 3 dup
 4 invokespecial #3 <com/yi/ErrorTest.<init> : ()V>
 7 astore_1
 8 iconst_0
 9 istore_2
10 aload_1
11 iload_2
12 invokevirtual #4 <com/yi/ErrorTest.fermin : (I)V>
15 iload_2
16 iinc 2 by 1
19 istore_2
20 getstatic #5 <java/lang/System.out : Ljava/io/PrintStream;>
23 iload_2
24 invokevirtual #6 <java/io/PrintStream.println : (I)V>
27 return

我们从第 8 行进行分析,这个是主要的部分
第8 : 将int类型的0入栈,就是放到操作数栈顶
第9 : 将操作数栈顶的值0弹出,保存到局部变量表index值为2的位置。(该方法是类方法所以index0的位置不会保存this,方法内公有三个参数 (args,inc,i))
第10 :将index1位置的引用类型推入栈顶
第11 :将局部变量表中index 2 位置的值的副本入栈(栈顶的值为0)
第12 : 进行方法调用
第15 :将局部变量表中index 2 位置的值的副本入栈(栈顶的值为0)
第16 :iinc是对int类型的值进行自增操作,后面第一个数值2 表示,局部变量表中的index 值,说明要对此值进行iinc操作,第二个数值1表示要增加的数值(这是局部变量表index为2的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0)
第19 : 将操作数栈顶的值弹出(值0),放到局部变量表index为2的位置(旧值:1,新值 :0),覆盖了上一步局部变量表的计算结果
总结在第9和第19执行了2次将0赋值给变量i的操作(=号赋值),i++操作时在这两次操作之间执行,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最好的文酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值