Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of invokeinterface?

Tags:

jvm

I'm reading this article about how JVM invokes methods, and I think I got most of it. However, I'm still having trouble understanding the need for invokeinterface.

The way I understand it, a class basically has a virtual table of methods and when calling a method with either invokevirtual or invokeinterface this virtual table is consulted.

What is the difference, then, between a method that's defined on an interface and a method defined on a base class? Why the different bytecodes?

The description of the instructions also looks very similar.

The article seems to claim that the method table of an interface can have "different offsets" every time a method is called. What I don't understand is why an interface would have a method table at all, since no object can have the interface as its actual type.

What am I missing?

like image 423
itsadok Avatar asked Oct 01 '09 15:10

itsadok


People also ask

What is invokespecial?

The invokespecial instruction is used to invoke instance initialization methods as well as private methods and methods of a superclass of the current class. In other words, invokespecial is used to call methods without concern for dynamic binding, in order to invoke the particular class' version of a method.

What is Invokevirtual in Java?

invokevirtual retrieves the Java class for objectref, and searches the list of methods defined by that class and then its superclasses, looking for a method called methodname, whose descriptor is descriptor. Once a method has been located, invokevirtual calls the method.

How the Java virtual machine handles method invocation and return?

When the JVM invokes a method, it creates a stack frame of the proper size for that method. Adding a new frame onto the Java stack when a method is invoked is called "pushing" a stack frame; removing a frame when a method returns is called "popping" a stack frame. The Java stack is made up solely of these frames.


2 Answers

Each Java class is associated with a virtual method table that contains "links" to the bytecode of each method of a class. That table is inherited from the superclass of a particular class and extended with regard to the new methods of a subclass. E.g.,

class BaseClass {     public void method1() { }     public void method2() { }     public void method3() { } }  class NextClass extends BaseClass {     public void method2() { } // overridden from BaseClass     public void method4() { } } 

results in the tables

BaseClass 1. BaseClass/method1() 2. BaseClass/method2() 3. BaseClass/method3()  NextClass 1. BaseClass/method1() 2. NextClass/method2() 3. BaseClass/method3() 4. NextClass/method4()

Note, how the virtual method table of NextClass retains the order of entries of the table of BaseClass and just overwrites the "link" of method2() which it overrides.

An implementation of the JVM can thus optimize a call to invokevirtual by remembering that BaseClass/method3() will always be the third entry in the virtual method table of any object this method will ever be invoked on.

With invokeinterface this optimization is not possible. E.g.,

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() { } } 

This class hierarchy results in the virtual method tables

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

As you can see, AnotherClass contains the interface's method in its fifth entry and MyClass contains it in its second entry. To actually find the correct entry in the virtual method table, a call to a method with invokeinterface will always have to search the complete table without a chance for the style of optimization that invokevirtual does.

There are additional differences like the fact, that invokeinterface can be used together with object references that do not actually implement the interface. Therefore, invokeinterface will have to check at runtime whether a method exists in the table and potentially throw an exception.

like image 108
janko Avatar answered Oct 22 '22 01:10

janko


Comparing both instructions in the JVM Spec, the very first difference is that invokevirtual checks the accessibility of the method during the lookup, while invokeinterface doesn't.

like image 23
ATorras Avatar answered Oct 22 '22 02:10

ATorras