Issue
Consider below class hierarchy.
class ClassA {
private void hello() {
System.out.println("Hello from A");
}
}
interface Myinterface {
default void hello() {
System.out.println("Hello from Interface");
}
}
class ClassB extends ClassA implements Myinterface {
}
public class Test {
public static void main(String[] args) {
ClassB b = new ClassB();
b.hello();
}
}
Running the program will give following error :
Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.testing.ClassA.hello()V from class com.testing.Test
at com.testing.Test.main(Test.java:23)
- This is all because I marked ClassA.hello as private.
- If I mark ClassA.hello as protected or remove the visibility modifier(i.e. making it default scope), then it shows a compiler error as :
The inherited method ClassA.hello() cannot hide the public abstract method in Myinterface
However, as per exception stacktrace above, I get a runtime IllegalAccessError.
I couldn't get why this is not detected at compile time. Any clues ?
Solution
Update: Seems like it's really a bug.
A class or super-class method declaration always takes priority over a default method!
default hello(...)
method from the Myinterface
allows you to write without errors:
ClassB b = new ClassB();
b.hello();
Until runtime, because at runtime hello(...)
method from the ClassA
takes the highest priority (but the method is private). Therefore, IllegalAccessError
occurs.
If you remove the default hello(...)
method from the interface, you get the same illegal access error, but now at compile time.
Answered By - Oleksandr Pyrohov
Answer Checked By - Pedro (JavaFixing Volunteer)