From this site
The answer can be easily found if one reads the Java VM Spec carefully:
The difference between the invokespecial and the invokevirtual instructions is that invokevirtual invokes a method based on the class of the object. 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.
There are several cases where its important to dispatch a method call "without concern for dynamic binding":
First, when chaining from one constructor to a super-class constructor.
Second, as in super.foo()
when calling from a method to a super-class's implementation. If the class, or any sub-class of it overrode that method, then invokevirtual would go to the wrong place.
Third, when a class wants to pick which default
version of a method to use as in
interface I { void f(); }
interface J extends I { default void f() { ... } }
interface K extends I { default void f() { ... } }
class C implements J, K {
@Override public void f() { K.super.f(); }
}
class C
above has a diamond inheritance problem, so it needs to pick which default method to invoke. invokespecial allows it to dispatch to K
's version, but if K.super.f
dispatched via invokevirtual the call would end up back at C.f
.