Спецификация языка Java обязывает класс переопределять только те методы, к которым он имеет доступ.Если метод суперкласса недоступен, он затеняется, а не переопределяется.
Отражение «работает», потому что вы запрашиваете у Outside.class
метод run.Если вместо этого вы спросите Base.class
, вы получите супер реализацию:
Method m = Base.class.getDeclaredMethod("run");
m.setAccessible(true);
m.invoke(p);
Чтобы убедиться, что метод считается недоступным, выполните:
public class Outside extends Base {
@Override
public void run() {
System.out.println("Outside.");
super.run(); // throws an IllegalAccessError
}
}
Итак, почемуметод не доступен?Я не совсем уверен, но я подозреваю, что так же, как классы с одинаковыми именами, загружаемые разными загрузчиками классов, приводят к разным классам времени выполнения, пакеты с одинаковыми именами, загружаемые разными загрузчиками классов, приводят к разным пакетам времени выполнения.
Редактировать: На самом деле, API отражения говорит, что это тот же пакет:
Base.class.getPackage() == p.getClass().getPackage() // true