invokeinterface是什么意思?

我正在阅读这篇关于JVM如何调用方法的文章 ,而且我想我得到了大部分。 但是,我仍然无法理解对invokeinterface的需求。

我理解的方式是,一个类基本上有一个虚拟表的方法,当用invokeinterfaceinvokeinterface调用一个方法时,这个虚拟表被查阅。

然后,在接口上定义的方法和在基类上定义的方法之间有什么区别? 为什么不同的字节码?

说明的描述也看起来非常相似。

文章似乎声称每次调用方法时,接口的方法表都可以有“不同的偏移量”。 我不明白为什么一个接口将有一个方法表,因为没有对象可以将接口作为它的实际types。

我错过了什么?

2 Solutions collect form web for “invokeinterface是什么意思?”

每个Java类都与一个虚拟方法表相关联,该包含一个类的每个方法的字节码的“链接”。 该表是从一个特定类的超类inheritance而来的,并针对一个子类的新方法进行了扩展。 例如,

 class BaseClass { public void method1() { } public void method2() { } public void method3() { } } class NextClass extends BaseClass { public void method2() { } // overridden from BaseClass 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() 

请注意, NextClass的虚拟方法表如何保留BaseClass表的条目顺序,并只覆盖它所覆盖的method2()的“链接”。

因此,JVM的实现可以通过记住BaseClass/method3()永远是该方法将被调用的任何对象的虚拟方法表中的第三项来优化对BaseClass/method3()调用。

使用invokeinterface这个优化是不可能的。 例如,

 interface MyInterface { void ifaceMethod(); } class AnotherClass extends NextClass implements MyInterface { public void method4() { } // overridden from NextClass public void ifaceMethod() { } } class MyClass implements MyInterface { public void method5() { } public void ifaceMethod() { } } 

这个类层次结果导致虚拟方法表

  AnotherClass
 1. BaseClass / method1()
 2. NextClass / method2()
 3. BaseClass / method3()
 4. AnotherClass / method4()
 5. MyInterface / ifaceMethod()

我的课
 1. MyClass / method5()
 2. MyInterface / ifaceMethod() 

如您所见, AnotherClass在第五个条目中包含接口的方法,而MyClass在第二个条目中包含它。 要真正在虚方法表中find正确的条目,对带有invokeinterface的方法的调用总是必须search完整的表,而没有机会调用invokeinterface的优化样式。

还有其他的区别,例如invokeinterface可以和实际上不实现接口的对象引用一起使用。 因此, invokeinterface将不得不在运行时检查表中是否存在方法,并可能抛出exception。 如果你想深入探讨这个话题,我build议,例如, “Java接口的高效实现:调用接口被认为是无害的” 。

比较JVM规范中的两条指令,第一个区别是invokeinterface在查找过程中检查方法的可访问性,而invokeinterface则不检查。

  • 安装Android Studio时,不会指向有效的JVM安装错误
  • 爪哇GC:为什么两个幸存者地区?
  • 提高性能一致性的方法
  • Java的String常量池在哪里生活,堆或栈?
  • 在Java中使用break来退出循环是不好的做法吗?
  • 使用debugging参数debuggingJava应用程序而不启动JVM
  • 使用JAVA_OPTS envvariables运行java
  • 在运行时设置JVM堆大小