Suppose the following real-life code structure:
interface I {
I m();
}
abstract class A implements I {
@Override
public abstract A m();
abstract class B extends A {
}
}
The bytecode generated for B is
abstract class A$B extends A {
<some stuff>
public I m(); //bridge method
Code:
0: aload_0
1: invokespecial #2 // Method A.m:()LA;
4: areturn
}
Notice the use of invokespecial instruction pointing to the abstract method A.m(). In my opinion this must lead to an AbstractMethodError at runtime according to JVM 8 specification on invokespecial:
If all of the following are true, let C be the direct superclass of the current class.
So A will be chosen as C in our example.
The actual method to be invoked is selected by the following lookup procedure.
1) If C contains a declaration for an instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.
So JVM will choose the A.m().
But the Run-time Exceptions section states that:
Otherwise, if step 1, step 2, or step 3 of the lookup procedure selects an abstract method, invokespecial throws an AbstractMethodError.
So invocation of the method will end up with the error.
I'm just wondered, why does Java compiler generate such sentenced-to-fail bytecode?
P.S. I have a guess that the above bridge method will never be called at all because the eventual implementor of class A.B will override it. But then the following question appears: for what purpose does java generate this bridge method?