Jvm 调用接口的意义是什么?

Jvm 调用接口的意义是什么?,jvm,Jvm,我正在阅读JVM是如何调用方法的,我想我已经了解了其中的大部分内容。但是,我仍然无法理解invokeinterface的需要 按照我的理解,一个类基本上有一个虚拟的方法表,当使用invokevirtual或invokeinterface调用一个方法时,会参考这个虚拟表 那么,在接口上定义的方法和在基类上定义的方法之间有什么区别呢?为什么字节码不同 这张照片看起来也很相似 这篇文章似乎声称,每次调用一个方法时,接口的方法表可以有“不同的偏移”。我不明白的是,为什么接口会有一个方法表,因为没有对象可

我正在阅读JVM是如何调用方法的,我想我已经了解了其中的大部分内容。但是,我仍然无法理解
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进行优化。原因已经在答案中(可以实现许多接口,并且参考表不是固定的)。