Статический порядок инициализации Java

Я пытаюсь обнаружить порядок, в котором происходит инициализация, или, скорее, причина, почему происходит инициализация в этом порядке. Учитывая код:

public class Main { { System.out.printf("NON-STATIC BLOCK\n"); } static{ System.out.printf("STATIC BLOCK\n"); } public static Main m = new Main(); public Main(){ System.out.printf("MAIN CONSTRUCTOR\n"); } public static void main(String... args) { //Main m = new Main(); System.out.printf("MAIN METHOD\n"); } } 

Вывод:

 STATIC BLOCK NON-STATIC BLOCK MAIN CONSTRUCTOR MAIN METHOD 

Однако, перемещение объявления m перед блоком инициализации вызывает:

 NON-STATIC BLOCK MAIN CONSTRUCTOR STATIC BLOCK MAIN METHOD 

и я совершенно не знаю, почему это происходит в этом порядке. Кроме того, если я исключаю ключевое слово static в объявлении m , ни блок init, ни огонь конструктора. Может ли кто-нибудь помочь мне с этим?

Я думаю, что вам просто не хватает раздела 12.4.2 JLS , который включает:

Затем выполните либо инициализаторы переменной classа, либо статические инициализаторы classа, или инициализаторы поля интерфейса, в текстовом порядке, как если бы они были одним блоком.

Часть «в текстовом порядке» является важным битом.

Если вы измените m на статическую переменную на переменную экземпляра, тогда поле не будет инициализировано инициализацией classа – оно будет инициализироваться только инициализацией экземпляра (т. Е. При создании экземпляра). На данный момент это вызовет переполнение стека – для создания одного экземпляра требуется создать другой экземпляр, который требует создания другого экземпляра и т. Д.

EDIT: Аналогично в разделе 12.5 задается инициализация экземпляра, включая следующие этапы:

  • Выполните инициализаторы экземпляра и инициализаторы переменных экземпляра для этого classа, присваивая значения инициализаторов переменных экземпляра соответствующим переменным экземпляра в порядке слева направо, в котором они отображаются в текстовом виде в исходном коде для classа. Если выполнение любого из этих инициализаторов приводит к исключению, то никакие новые инициализаторы не обрабатываются, и эта процедура завершается внезапно с тем же исключением. В противном случае перейдите к шагу 5.

  • Выполните оставшуюся часть тела этого конструктора. Если это выполнение завершается внезапно, то эта процедура завершается внезапно по той же причине. В противном случае эта процедура завершится нормально.

Вот почему вы видите «НЕСТАТИЧЕСКИЙ БЛОК» до «ГЛАВНОГО КОНСТРУКТОРА».

  • spannable на android для textView
  • Java: как получить входные данные из System.console ()
  • Драйвер JDBC PostgreSQL с Android
  • Поместить внешнюю библиотеку в JAR?
  • onInterceptTouchEvent получает только ACTION_DOWN
  • java: Class.isInstance vs Class.isAssignableFrom
  • Использование пользовательского шрифта в android TextView с помощью xml
  • Отсутствует оператор return для оператора if / else
  • Почему возникает ArrayIndexOutOfBoundsException и как его избежать в Android?
  • Вычисление угла между линией, определяемой двумя точками
  • Не удается получить местоположение и электронную почту с помощью API Facebook
  • Давайте будем гением компьютера.