Ответ 1
Я знаю, что статический блок выполняется только тогда, когда объект класса инициализирован или делается статическая ссылка. Но здесь я не сделал ни одного из них для класса Sub.
Ваш код не работает, но для этого main
для запуска нужно загружать Sub
. Поэтому запускается статический инициализатор для него.
Например, я предполагаю, что вы запускали его следующим образом:
java Sub
Инструмент java
должен загрузить Sub
, чтобы вызвать Sub.main
. Это статическая ссылка (доступ, действительно), вызывающий запуск статического инициализатора. (Если вы запустили его в среде IDE, среда IDE выполнит часть инструмента java
, но результат будет таким же.)
Итак, вот что произошло:
-
java
запускает загрузкуSub
-
JVM должен загрузить
SuperClass
, чтобы загрузитьSub
-
Итак, мы видим, что их статические инициализаторы выполняются в порядке (
SuperClass
, затемSub
):super sub
-
java
вызовы инструментовmain
-
Код в
main
вызываетnew SuperClass
:Super
-
Код в
main
вызываетf.c()
2
-
Код в
main
вызываетSuperClass.b
:2
Как Holger указывает, это описывается спецификацией JVM в §5.5 - Инициализация и связанный с ним §5.2 - Запуск виртуальной машины Java:
Инициализация класса или интерфейса состоит в выполнении его метода инициализации класса или интерфейса (§2.9).
Класс или интерфейс C может быть инициализирован только в результате:
...
Если C - класс, инициализация одного из его подклассов.
Если C является классом, его обозначение как начальный класс при запуске виртуальной машины Java (§5.2).
Эта вторая точка пули покрывает SuperClass
, а последняя точка пули охватывает Sub
.