Статический порядок инициализации 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
перед блоком инициализации вызывает:
- Android написать в папку sd card
- Рассчитать количество будних дней между двумя датами в Java
- Как импортировать com.android.internal.telephony.ITelephony в приложение Android
- Stream Live Android Audio на сервер
- Почему окончательная переменная должна быть инициализирована до завершения конструктора?
NON-STATIC BLOCK MAIN CONSTRUCTOR STATIC BLOCK MAIN METHOD
и я совершенно не знаю, почему это происходит в этом порядке. Кроме того, если я исключаю ключевое слово static
в объявлении m
, ни блок init, ни огонь конструктора. Может ли кто-нибудь помочь мне с этим?
- андроид на прослушивателе изменения текста
- Ошибка конструктора списка Firebase
- Сканер next () бросает NoSuchElementException для некоторых онлайн-компиляторов
- Попытка чтения с консоли в Java
- Приложение распознавания речи Android без всплывающих окон
- Как переместить / переименовать файл из внутреннего хранилища приложений во внешнее хранилище на Android?
- Рабочий многоточечный запрос POST с волейболом и без HttpEntity
- Как я могу перечислять все classы в пакете и добавлять их в список?
Я думаю, что вам просто не хватает раздела 12.4.2 JLS , который включает:
Затем выполните либо инициализаторы переменной classа, либо статические инициализаторы classа, или инициализаторы поля интерфейса, в текстовом порядке, как если бы они были одним блоком.
Часть «в текстовом порядке» является важным битом.
Если вы измените m
на статическую переменную на переменную экземпляра, тогда поле не будет инициализировано инициализацией classа – оно будет инициализироваться только инициализацией экземпляра (т. Е. При создании экземпляра). На данный момент это вызовет переполнение стека – для создания одного экземпляра требуется создать другой экземпляр, который требует создания другого экземпляра и т. Д.
EDIT: Аналогично в разделе 12.5 задается инициализация экземпляра, включая следующие этапы:
Выполните инициализаторы экземпляра и инициализаторы переменных экземпляра для этого classа, присваивая значения инициализаторов переменных экземпляра соответствующим переменным экземпляра в порядке слева направо, в котором они отображаются в текстовом виде в исходном коде для classа. Если выполнение любого из этих инициализаторов приводит к исключению, то никакие новые инициализаторы не обрабатываются, и эта процедура завершается внезапно с тем же исключением. В противном случае перейдите к шагу 5.
Выполните оставшуюся часть тела этого конструктора. Если это выполнение завершается внезапно, то эта процедура завершается внезапно по той же причине. В противном случае эта процедура завершится нормально.
Вот почему вы видите «НЕСТАТИЧЕСКИЙ БЛОК» до «ГЛАВНОГО КОНСТРУКТОРА».