序言
返景入深林,复照青苔上。
前一阵分析Jimple文件,看到好多种invoke语句,今天来复习一下。
两种链接
静态链接
当一个class文件被装进JVM内部时,如果被调用的目标方法在编译期可知,且运行时保持不变。
动态链接
如果调用的方法在编译器无法确定下来,只能在运行期间确定下来(重写/多态/继承)。
两种方法
非虚方法
静态方法static
,私有方法private
,final
方法,构造器<init>
,父类方法super.xx()
虚方法
多态,重写,重载。
五种invoke
invokestatic
调用静态方法static
,解析阶段唯一确定方法的版本。
invokespecial
调用促使构造器方法<init>
,私有方法private
,父类方法super.xx()
。
解析阶段确定唯一方法的版本。
invokevirtual
虚方法,以及final
方法。
invokeinterface
调用xx接口
invokedynamic
动态解析出需要调用的方法,然后执行。
lambda表达式。
说明
- 非虚方法:invokestatic,invokespecial
- 虚方法:invokevirtual,invokedynamic
- 特殊说明:
final
方法其实很特殊,他是唯一一个invokevirtual,却仍然是非虚方法。 - invokedynamic主要还是应用于lambda表达式,比较少见
实例
父类Father:
1 | class Father{ |
子类Son继承了Father父类:
1 | public class Son extends Father{ |
说明:
- 重点还是各种方法的调用。
- 第一个
showStatic("niceday")
是Son子类自己的static方法。 - 第二个
Father.showStatic("good")
,是父类的static方法。 - 第三个
showPrivate("hello")
,是子类自己的private方法。 - 第四个和第五个方法都是继承父类的方法,分别是父类的正常方法和父类的final方法。
下面看一下字节码,对应关系如下: