#java
#java
Вопрос:
Я хочу подтвердить, как компилятор Java генерирует блок инициализации копий в любых конструкторах. Я думаю следующим образом.
случай 1) если конструктор вызывает другой перегруженный конструктор, компилятор Java может не сгенерировать копию блока инициализации.
случай 2) если конструктор не использует другой перегруженный конструктор, компилятор Java может сгенерировать копию блока инициализации.
Правильно ли я понимаю?
Следующий документ является выдержкой из руководства oracle.
https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
Инициализация членов экземпляра
Обычно вы помещаете код для инициализации переменной экземпляра в конструктор. Существует две альтернативы использованию конструктора для инициализации переменных экземпляра: блоки инициализатора и конечные методы.
Блоки инициализатора для переменных экземпляра выглядят точно так же, как блоки статического инициализатора, но без ключевого слова static:
….
Компилятор Java копирует блоки инициализатора в каждый конструктор.
<<<<<<<<<<< Следовательно, этот подход может быть использован для совместного использования блока кода между несколькими конструкторами. <<<<<<<<<<
Ниже приведен пример кода.
public class SampleClass {
int id = 0;
static int seqID=1000;
static{
System.out.println("static initialization block: seqID=" seqID);
}
{
seqID ;
System.out.println("initialization block: seqID=" seqID);
}
public SampleClass(int id){
System.out.println("constructor start");
this.id = id;
//this.id = seqID;
System.out.println("constructor end");
}
public SampleClass() {
this(seqID);
}
public void func() {
System.out.println("seqID=" seqID " this.id=" this.id);
}
public static void main(String[]args ) {
SampleClass a=new SampleClass(SampleClass.seqID);
a.func();
SampleClass b=new SampleClass();
b.func();
}
}
== результат выполнения ==
static initialization block: seqID=1000
initialization block: seqID=1001
constructor start
constructor end
seqID=1001 this.id=1000
initialization block: seqID=1002
constructor start
constructor end
seqID=1002 this.id=1001
Я исследовал байтовый код этого примера кода, а затем компилятор Java генерирует копию
блока инициализации только в конструкторе Sample (int).
(Компилятор Java не генерирует копию блока инициализации в конструкторе Sample().)
Комментарии:
1. Да, вы правы.
Compiler does not copy the initialization block in case there is an explicit constructor invoked
. УтверждениеThe Java compiler copies initializer blocks into every constructor.
вводит в заблуждение. Раздел, docs.oracle.com/javase/specs/jls/se15/html/jls-12.html , в некоторой степени объясняет последовательность операций по созданию экземпляра. Там мы видим, что шаги 3 и 4 будут пропущены, если есть явный вызов конструктора.2. Спасибо за ваш комментарий. Мне стоит того, чтобы я мог подтвердить поведение компилятора Java. Я ценю ваш хороший ответ. Я подробно рассмотрю приведенный выше документ.