深入java虚拟机 方法调用指令
1 方法调用指令
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指令来实现,退出当前方法栈,从栈顶弹出返回值,压入调用方法的栈