Static method in a superclass is interfering with the default method list creation.
interface I {
default String foo() {
return "default";
}
}
public class A {
public static String foo() { return "static"; }
}
public class B extends A implements I {
public static void main(String[] args) {
try {
System.out.println(new B().foo());
} catch (Throwable t) {
System.out.println("invokevirtual: new B().foo() -> " + t);
}
try {
System.out.println(((I)(new B())).foo());
} catch (Throwable t) {
System.out.println("invokeinterface: ((I)(new B()).foo() -> " + t);
}
}
}
See attached.
When i compile (separately) and run using tl or hotspot-rt the output is:
invokevirtual: new B().foo() -> java.lang.IncompatibleClassChangeError: Expecting non-static method B.foo()Ljava/lang/String;
invokeinterface: ((I)(new B()).foo() -> java.lang.AbstractMethodError: B.foo()Ljava/lang/String;
My initial translation of this is that the first example is behaving correctly.
The second example looks like a bug to me - I believe invokeinterface ((new B()).foo() should print "default")
Note: inside the code, the default method processing is not finding any slots to fill, so
the initial miranda list appears to not contain foo().