Вызов метода по умолчанию в интерфейсе при конфликте с приватным методом
Рассмотрим ниже иерархию классов.
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();
}
}
Запуск программы даст следующую ошибку:
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)
- Это все потому, что я обозначил ClassA.hello как закрытый.
- Если я помечаю ClassA.hello как защищенный или удаляю модификатор видимости (т.е. Делая его по умолчанию), тогда он показывает ошибку компилятора как:
The inherited method ClassA.hello() cannot hide the public abstract method in Myinterface
Однако, согласно вышеописанному исключению stacktrace, я получаю runtime IllegalAccessError.
Я не мог понять, почему это не обнаружено во время компиляции. Любые подсказки?
Ответы
Ответ 1
Обновление: Кажется, это действительно ошибка.
Объявление класса или суперкласса всегда имеет приоритет над методом по умолчанию!
метод default hello(...)
из Myinterface
позволяет писать без ошибок:
ClassB b = new ClassB();
b.hello();
До запуска, потому что во время выполнения hello(...)
метод из ClassA
принимает наивысший приоритет (но метод является приватным). Поэтому происходит IllegalAccessError
.
Если вы удалите метод hello(...)
по умолчанию из интерфейса, вы получите ту же ошибку незаконного доступа, но теперь во время компиляции.