Java. Почему блок экземпляра вызывается после конструктора или порядка в конструкторе?

Поскольку мы знаем, что instance block вызывается перед constructor. Технические характеристики, Ответ на переполнение стека и т. д.

Итак, вывод, который мы ожидаем от кода ниже:

class Test{
    static { System.out.println("Static Block"); }
    { System.out.println("Instance Block"); }
    Test(){
        System.out.println("Constructor Body");
        { System.out.println("Constructor Instance Block"); }
    }
}
class TestApp{
    public static void main(String[] args){
        new Test();
    }
} 

Должно быть:

Static Block
Instance Block

Constructor Instance Block
Constructor Body

Тогда почему я получаю следующий вывод:

Static Block
Instance Block

Constructor Body
Constructor Instance Block

Но если я изменю порядок операторов в constructor, например:

class Test{
    static { System.out.println("Static Block"); }
    { System.out.println("Instance Block"); }
    Test(){
        { System.out.println("Constructor Instance Block"); }
        System.out.println("Constructor Body");
    }
}

Затем он выводит ожидаемый результат, но этого не должно быть, потому что в документах говорится, что instance block вызывается перед constructor.

Почему instance block вызывается после тела constructor или мы можем сказать, почему он вызывается по порядку?


person Stack Overflow    schedule 20.12.2018    source источник
comment
{ System.out.println("Constructor Instance Block"); } не является блоком инициализации. Это просто случайный блок кода в конструкторе.   -  person ernest_k    schedule 20.12.2018
comment
Не существует такого понятия, как блок экземпляра конструктора. Весь код внутри любого метода или конструктора выполняется по порядку. (Ну, за исключением некоторых оптимизаций компилятора, но это уже другая история.)   -  person MC Emperor    schedule 20.12.2018
comment
Инициализаторы экземпляра не вызываются перед конструктором. Они встроены во все конструкторы, которые вызывают super, между вызовом super и остальной частью тела этого конструктора.   -  person Andy Turner    schedule 20.12.2018
comment
Где instance blocks и static blocks применимы и разрешены для использования в их реальном значении, одно место, которое я знаю, это class, есть ли другие места, где они также применимы?   -  person Stack Overflow    schedule 20.12.2018


Ответы (2)


{ System.out.println("Constructor Instance Block"); } - это не instance block, а еще одна общая строка кода в методе (в вашем случае конструктор). Так что это происходит ПОСЛЕ System.out.println("Constructor Body"); , что естественно.

person ZhaoGang    schedule 20.12.2018
comment
Итак, вы имеете в виду, что в constructor нет концепции instance block и static block? - person Stack Overflow; 20.12.2018
comment
Точно. Они используются внутри класса, а не метода (конструктор также является методом). - person ZhaoGang; 20.12.2018
comment
Пожалуйста, не могли бы вы сказать, где instance blocks и static blocks применимы и разрешены для использования в их реальном значении, одно место, которое, как я знаю, находится в class, есть ли другие места, где они также применимы? - person Stack Overflow; 20.12.2018
comment
Насколько я знаю, их можно использовать только внутри класса. - person ZhaoGang; 20.12.2018
comment
@SunnyKhan Также обратите внимание, что их нельзя поместить во внутренний класс, но можно поместить в статический вложенный класс (у которого есть ключевое слово static). - person ZhaoGang; 20.12.2018
comment
@ZhaoGang правильно. Они могут отображаться только в ClassBodyDeclaration. - person Andy Turner; 20.12.2018
comment
@ZhaoGang - Вы имеете в виду class{ class{ ... } } и static class{ class{ ... } }? - person Stack Overflow; 20.12.2018
comment
@Sunny Khan Вы можете прочитать дальше здесь: stackoverflow.com/questions/70324/ - person ZhaoGang; 20.12.2018

static initializers и instance initializers соответствуют классу и его созданию. См.: Статический блок и блок инициализатора в Java? Вот почему он должен быть помещен в body класса.

В противном случае (например, в теле метода) ваш {...} будет рассматриваться как блок инструкций (как в языке C). Если вы попытаетесь поместить конструкцию static {...} в другое место (не в тело класса), вы получите ошибку компиляции.

Надеюсь, ответ помог вам!

person TheSilenceOfMind    schedule 20.12.2018