Читая книгу Эккеля, натолкнулся на один момент, который не могу понять. Представлен следующий код:
import static net.mindview.util.Print.*;
class Insect {
private int i = 9;
protected int j;
Insect() {
print("i = " + i + ", j = " + j);
j = 39;
}
private static int x1 = printInit("static Insect.x1 initialized");
static int printInit(String s) {
print(s);
return 47;
}
}
public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized");
public Beetle() {
print("k = " + k);
print("j = " + j);
}
private static int x2 = printInit("static Beetle.x2 initialized");
public static void main(String[] args) {
print("Beetle constructor");
Beetle b = new Beetle();
}
}
OUTPUT:
static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 47
j = 39
Всегда думал, что перед вызовом конструктора, должны проиницилизоваться поля класса, чтобы в случае обращения к неициализирвоанной переменной в конструкторе не получить исключение. Следуя этой логике вывод на экран надписи "Beetle.k initialized" должен был быть после вывода "Beetle constructor". Прощу помочь разобраться. Спасибо.
Ответ
Порядок инициализации таков:
Статические элементы родителя
Статические элементы наследника
Глобальные переменные родителя
Конструктор родителя
Глобальные переменные наследника
Конструктор наследника
Пример
class Insect {
private int i = 9; [9]
protected int j; [10]
Insect() { [8]
print("i = " + i + ", j = " + j); [11]
j = 39; [12]
}
private static int x1 = printInit("static Insect.x1 initialized"); [2]
static int printInit(String s) { [3]
print(s);
return 47;
}
}
public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized"); [13]
public Beetle() { [7]
print("k = " + k); [14]
print("j = " + j); [15]
}
private static int x2 = printInit("static Beetle.x2 initialized"); [4]
public static void main(String[] args) { [1]
print("Beetle constructor"); [5]
Beetle b = new Beetle(); [6]
}
}
Комментариев нет:
Отправить комментарий