深入java虚拟机 方法调用指令

1 方法调用指令

  
深入java虚拟机 方法调用指令_第1张图片
 
深入java虚拟机 方法调用指令_第2张图片
 

2 实例方法,类方法

   调用实例方法时, 虚拟机从所调用方法栈内的操作数栈中弹出objectref和args, 虚拟机把objectref作为局部变量0放到新的栈中, 把所有args作为变量1,2,。。。等处理,objectref是隐式传给所有实例方法的this指针   调用类方法时, 虚拟机只从所调用方法栈桢中的操作数栈中弹出参数,并将它们放到新的栈桢中作为局部变量0, 1,2。。。

   例1 实例方法调用:

  

    public int test (int x, int y) {
        System.out.println(this);
        return x + y;
    }

    字节码:

  

getstatic java/lang/System/out Ljava/io/PrintStream;
aload_0  //获取位置为0的对象引用(this)压入栈(调用当前方法时,虚拟机会把this隐式的压入当前方法栈的位置为0的变量上)
invokevirtual java/io/PrintStream/println(Ljava/lang/Object;)V //调用println方法
iload_1 //获取位置为1的局部变量,压入栈(调用当前方法时,虚拟机会把第一个参数压入当前方法栈的位置为1的变量上)
iload_2 //获取位置为2的局部变量,压入栈(调用当前方法时,虚拟机会把第二个参数压入当前方法栈的位置为2的变量上)
iadd  //栈顶两个int类型的变量相加,结果压入栈
ireturn //返回栈顶的int值

 

   例2 类方法调用

  

    public static int testStatic (int x, int y) {
        return x + y;
    }

   字节码:

  

iload_0 //获取位置为0的int值压入栈(调用当前方法时,虚拟机会把第一个参数压入当前方法栈的位置为0的变量上)
iload_1 //获取位置为1的int值压入栈(调用当前方法时,虚拟机会把第二个参数压入当前方法栈的位置为1的变量上)
iadd  //栈顶的两个int值相加,结果压入栈顶
ireturn //返回栈顶int值

   

3 实例方法特殊调用

   invokespecial, inovkeinterface

   invokespecial:根据引用类型来调用实例方法, 而不是根据对象的类来调用的时候,通常使用invokespecial指令,分一下三种情况:

      (1)实例初始化方法(init())方法

      (2)私有方法

      (3)使用super关键字调用的方法

   inovkeinterface

       当引用的类型为类的时候, 使用invokevirtual;当引用的类型为接口时,使用invokeinterface

 

4 方法返回

  方法的返回以类型+return指令来实现,退出当前方法栈,从栈顶弹出返回值,压入调用方法的栈

 
深入java虚拟机 方法调用指令_第3张图片
 

你可能感兴趣的:(方法调用,深入java虚拟机)