-
Bug
-
Resolution: Fixed
-
P3
-
None
-
b51
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8025355 | 8 | Karen Kinnear | P3 | Closed | Fixed | b109 |
The currently-specified behavior of resolution is that a private class method takes priority over an interface method. (This is a problem -- see JDK-8021581.)
When default methods are involved, this rule is not being followed, and there are some inconsistencies.
Example 1 is the expected behavior for all 3 cases.
There may be some similar inconsistencies when package-access methods are involved.
-----
Example 1 (no default):
public class A {
private void m() { System.out.println("A.m"); }
public static void main(String... args) { B b = new C(); b.m(); }
}
public interface I {
public void m();
}
public abstract class B extends A implements I {
}
public class C extends B {
public void m() { System.out.println("C.m"); }
}
public class Test {
public static void main(String... args) { B b = new C(); b.m(); }
}
java Test
Exception in thread "main" java.lang.IllegalAccessError: tried to access method A.m()V from class Test
java A
A.m
-----
Example 2 (default, overridden):
public class A {
private void m() { System.out.println("A.m"); }
public static void main(String... args) { B b = new C(); b.m(); }
}
public interface I {
public default void m() { System.out.println("I.m"); }
}
public abstract class B extends A implements I {
}
public class C extends B {
public void m() { System.out.println("C.m"); }
}
public class Test {
public static void main(String... args) { B b = new C(); b.m(); }
}
java Test
C.m
java A
C.m
-----
Example 3 (default, not overridden):
public class A {
private void m() { System.out.println("A.m"); }
public static void main(String... args) { B b = new C(); b.m(); }
}
public interface I {
public default void m() { System.out.println("I.m"); }
}
public abstract class B extends A implements I {
}
public class C extends B {
}
public class Test {
public static void main(String... args) { B b = new C(); b.m(); }
}
java Test
Exception in thread "main" java.lang.IllegalAccessError: tried to access method A.m()V from class B
java A
Exception in thread "main" java.lang.IllegalAccessError: tried to access method A.m()V from class B
When default methods are involved, this rule is not being followed, and there are some inconsistencies.
Example 1 is the expected behavior for all 3 cases.
There may be some similar inconsistencies when package-access methods are involved.
-----
Example 1 (no default):
public class A {
private void m() { System.out.println("A.m"); }
public static void main(String... args) { B b = new C(); b.m(); }
}
public interface I {
public void m();
}
public abstract class B extends A implements I {
}
public class C extends B {
public void m() { System.out.println("C.m"); }
}
public class Test {
public static void main(String... args) { B b = new C(); b.m(); }
}
java Test
Exception in thread "main" java.lang.IllegalAccessError: tried to access method A.m()V from class Test
java A
A.m
-----
Example 2 (default, overridden):
public class A {
private void m() { System.out.println("A.m"); }
public static void main(String... args) { B b = new C(); b.m(); }
}
public interface I {
public default void m() { System.out.println("I.m"); }
}
public abstract class B extends A implements I {
}
public class C extends B {
public void m() { System.out.println("C.m"); }
}
public class Test {
public static void main(String... args) { B b = new C(); b.m(); }
}
java Test
C.m
java A
C.m
-----
Example 3 (default, not overridden):
public class A {
private void m() { System.out.println("A.m"); }
public static void main(String... args) { B b = new C(); b.m(); }
}
public interface I {
public default void m() { System.out.println("I.m"); }
}
public abstract class B extends A implements I {
}
public class C extends B {
}
public class Test {
public static void main(String... args) { B b = new C(); b.m(); }
}
java Test
Exception in thread "main" java.lang.IllegalAccessError: tried to access method A.m()V from class B
java A
Exception in thread "main" java.lang.IllegalAccessError: tried to access method A.m()V from class B
- backported by
-
JDK-8025355 Default method resolution with private superclass method
-
- Closed
-
- relates to
-
JDK-8024804 Crash when InterfaceMethodref resolves to Object.registerNatives
-
- Closed
-
-
JDK-8021581 Private class methods interfere with invocations of interface methods
-
- Open
-