-
Bug
-
Resolution: Fixed
-
P2
-
hs25
-
b62
-
generic
-
generic
-
Not verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8030272 | 8u5 | Karen Kinnear | P2 | Resolved | Fixed | b01 |
JDK-8029933 | 8 | Karen Kinnear | P2 | Closed | Fixed | b120 |
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().
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().
- backported by
-
JDK-8030272 Lambda: default methods static superclass method masking default
- Resolved
-
JDK-8029933 Lambda: default methods static superclass method masking default
- Closed
- relates to
-
JDK-8029567 Clean up linkResolver code
- Resolved
-
JDK-8251990 Improve default method handling of private static methods in java.lang.Object
- Closed