[转载] java method invoke的指令简介
?
方法调用相关的jvm子令集主要有一下四种:
?
invokestatic?------------------------------->调用类方法(静态绑定,速度快)
?
invokevirtual?------------------------------>调用实例方法(动态绑定)
?
invokespecial?----------------------------->调用实例方法(静态绑定,速度快)
?
invokeinterface?--------------------------->调用引用类型为interface的实例方法(动态绑定)
?
invokedynamic?--------------------------->JDK 7引入的,主要是为了支持动态语言的方法调用。可参考
? ? ??New JDK 7 Feature: Support for Dynamically Typed Languages in the Java Virtual Machine
?
操作码??操作数说明
invokestaticindexbyte1,indexbyte2把args从stack中弹出,调用constant pool索引指向的实例方法
?
invokevirtualindexbyte1,indexbyte2把objectref和args从stack中弹出,调用constant pool索引指向的实例方法
?
invokespecialindexbyte1,indexbyte2把objectref和args从stack中弹出,调用constant pool索引指向的实例方法
?
invokeinterfaceindexbyte1,indexbyte2把objectref和args从stack中弹出,调用constant pool索引指向的实例方法
?
//-----------------------------------------------举例浅析区别----------------------------
invokevirtual和invokespecial的区别在于:invokespecial通常根据引用的类型选择方法,而不是对象的类来选择!即它使用静态绑定而不是动态绑定。
?
使用invokespecial指令分为下面三种情况:
1. 实例初始化方法(<init>())方法
2. 私有方法
3. 使用super关键字调用的方法
?
?
invokespecial and Private Methods
看下面一个例子:
?
4:???return??exampleMethod()首先将赋给局部变量0的reference压入stack(隐含参数this被传入给所有的实例方法),然后使用invokespecial指令通过这个引用调用interestingMethod()。
尽管这里的对象时Subclass的实例,而且Subclass类中的interestingMethod()方法也是能够访问的,但是JVM最终还是调用了Superclass类中的interestingMethod()方法。
程序的正确输出为:"Superclass's interesting method",因为这里生成的bytecode中调用的interestingMethod()使用的是invokespecial指令,而调用invokespecial指令时,JVM会按照你reference type来choice调用的method。
?
//-----------------------------指令调用和速度PK-------------------------------------------------------
可想而知,调用接口引用方法可能要比调用类引用方法慢。因为,当JVM遇到invokevirtual指令时,它把实例方法的符号引用解析为直接引用,所以生成的直接引用很可能是方法表中的一个偏移量,而且从此往后都可以使用同样的偏移量。但对于invokeinterface指令来说,虚拟机每一次遇到invokeinterface指令,都不能不重新搜寻一遍方法表,因为虚拟机不能够假设这一次的偏移量与上一次的偏移量相同。
最快的指令莫过于invokespecial和invokestatic,因为这些指令调用的都是静态绑定的,即在编译器确定了!所以当JVM为这些指令解析符号引用时,将符号引用转换成为直接饮用,所生成的直接引用将包含一个指向实际操作码的指针。
?
以上内容参考《深入Java虚拟机》
?
文章来源:http://boy00fly.iteye.com/blog/1158854
?