字节码中的常用指令

一道面试题,问最后输出多少?
 public static void main(String[] args) {
        int a = 10;
        a = a++; // 输出10
        //a = ++a; // 输出11
        System.out.println(a);
    }
上述代码对应的字节码指令

​ 一个main方法对应虚拟机栈的一个栈帧,下面所说的操作数栈就是栈帧中的操作数栈。对变量进行数学运算或者赋值等操作都要把操作数弹出栈。

使用a = a++ 后字节码的指令

  1. bipush : 将10 压入操作数栈
  2. istore_1:将10出栈,并赋值给局部变量表中下标为1(下标为0的是 this 变量)的变量a,完成赋值语句。
  3. iload_1:因为要对a进行赋值操作,把10压入操作数栈。
  4. iinc 1 by 1:但是在上一步最终完成赋值之前,要对a进行++操作,所以直接将局部变量表中下标为1即变量a进行加1,此时a = 11。
  5. istore_1:将操作数的的数弹出并赋值给a,a 又变成了10。所以最后输出10
使用a = ++a后的字节码指令

  1. bipush 10: 将10压入操作数栈
  2. istore_1:将10出栈,并赋值给局部变量表中下标为1的变量a,完成赋值语句。
  3. iinc 1 by 1:因为这里是先自加再赋值,所以将a + 1变成11。
  4. iload_1:现在执行赋值操作,所以先让11入操作数栈。
  5. istore_1:让11出栈,给a赋值。最终a = 11。
常用指令总结
  1. bipush: 压栈

  2. iload_x:将局部变量表中下标为x压入栈

  3. istore_x:将栈定数据弹出,赋值给局部变量中下标为x的变量

  4. iadd:将栈顶两个元素弹出,进行相加操作

  5. isub:将栈顶两个元素弹出,进行相减操作

  6. invokespecial:执行特殊方法,即不需要多态的方法。

    ​ 例如:private方法、构造方法

  7. invokevirtual:调用方法

  8. invokestatic:执行静态方法

.....

posted @ 2020-10-16 18:13  zcr小翟  阅读(280)  评论(0编辑  收藏  举报