Jvm 调用接口的意义是什么?
我正在阅读JVM是如何调用方法的,我想我已经了解了其中的大部分内容。但是,我仍然无法理解Jvm 调用接口的意义是什么?,jvm,Jvm,我正在阅读JVM是如何调用方法的,我想我已经了解了其中的大部分内容。但是,我仍然无法理解invokeinterface的需要 按照我的理解,一个类基本上有一个虚拟的方法表,当使用invokevirtual或invokeinterface调用一个方法时,会参考这个虚拟表 那么,在接口上定义的方法和在基类上定义的方法之间有什么区别呢?为什么字节码不同 这张照片看起来也很相似 这篇文章似乎声称,每次调用一个方法时,接口的方法表可以有“不同的偏移”。我不明白的是,为什么接口会有一个方法表,因为没有对象可
invokeinterface
的需要
按照我的理解,一个类基本上有一个虚拟的方法表,当使用invokevirtual
或invokeinterface
调用一个方法时,会参考这个虚拟表
那么,在接口上定义的方法和在基类上定义的方法之间有什么区别呢?为什么字节码不同
这张照片看起来也很相似
这篇文章似乎声称,每次调用一个方法时,接口的方法表可以有“不同的偏移”。我不明白的是,为什么接口会有一个方法表,因为没有对象可以将接口作为其实际类型
我遗漏了什么?比较中的两条指令,第一个区别是
invokevirtual
在查找过程中检查方法的可访问性,而invokeinterface
没有。每个Java类都与包含“链接”的虚拟方法表相关联类的每个方法的字节码。该表继承自特定类的超类,并根据子类的新方法进行扩展。例如:
类基类{
public void method1(){}
public void method2(){}
public void method3(){}
}
类NextClass扩展了基类{
public void method2(){}//从基类重写
public void method4(){}
}
表中的结果
BaseClass
1. BaseClass/method1()
2. BaseClass/method2()
3. BaseClass/method3()
NextClass
1. BaseClass/method1()
2. NextClass/method2()
3. BaseClass/method3()
4. NextClass/method4()
该类层次结构将生成虚拟方法表
AnotherClass
1. BaseClass/method1()
2. NextClass/method2()
3. BaseClass/method3()
4. AnotherClass/method4()
5. MyInterface/ifaceMethod()
MyClass
1. MyClass/method5()
2. MyInterface/ifaceMethod()
另一类
1.基类/方法1()
2.下一类/方法2()
3.基类/方法3()
4.另一类/方法4()
5.MyInterface/ifaceMethod()
类名
1.MyClass/method5()
2.MyInterface/ifaceMethod()
如您所见,
AnotherClass
在第五个条目中包含接口的方法,MyClass
在第二个条目中包含接口的方法。要在虚拟方法表中真正找到正确的条目,对具有invokeinterface
的方法的调用将始终必须搜索完整的表,而不需要像invokevirtual
那样进行优化
还有其他的区别,比如,
invokeinterface
可以与不实际实现接口的对象引用一起使用。因此,invokeinterface
必须在运行时检查表中是否存在某个方法,并可能引发异常。很有趣,但这可能就是它的全部内容吗?还有更多的区别(如其他地方所解释的,方法查找过程是不同的),但这种差异来自这样一个事实:接口中的所有方法(至少在Java8之前)都是公共的。因此,不需要对通过接口访问方法进行可见性检查,因为它们必须是公共的,这意味着所有代码都可以访问它们。我怀疑检查可访问性带来了什么?请参阅。它有一个虚拟方法表。表本身根本不是虚拟的;)“总是要搜索完整的表,而不需要像invokevirtual那样进行优化”——应该注意的是,它并不总是要搜索表,因为它可以进行不同的优化。有关更多详细信息,请参阅链接的“被认为是无害的”文章。因此,为什么需要invokeinterface
只使用invokevirtual
?@shaoyihe根据janko的回答,我认为这是为了性能,而invokeinterface不能作为invokevirtual进行优化。原因已经在答案中(可以实现许多接口,并且参考表不是固定的)。