Вопрос довольно простой, как многим может показаться.
В общем:
abstract class A {
int a = 8;
public A() {
show();
}
abstract void show();
}
class B extends A {
int a = 90;
void show() {
System.out.println("" + a);
}
}
И в методе main создаю объект класса B:
public static void main(String args[]) {
new B(); // output - 0
}
Оно и понятно, конструктор суперкласса вызовет полиморфную версию метода show (тем более в базовом классе он абстрактный). Контекст переменной
a поменяется (та, которая в классе B, ещё не успела инициализироваться значением 90, ведь это происходит в конструкторе?). Но ведь сначала при создании объекта B должен быть проинициализирован его родитель, все поля, которые там находятся. Когда же тогда JVM успевает проинициализировать поле
a нулём, если сначала вызывается конструктор суперкласса?
И вот вообще, если немного поменять код в классе B:
class B extends A {
int x = 90; // поменял название переменной!
void show() {
System.out.println("" + a); // 8
}
То напечатается значение переменной
a из контекста объекта
A - 8. Тут я ещё могу как-то понять, что инициализация переменной происходит до вызова ф-ции show. Типа того:
public A() {
super(); // Вызов конструктора Object`а
a = 8;
show();
}
Но когда успевает проинициализировать поле
a в контексте объекта B, если вообще сначала JVM работает над его базовым классом? И вообще есть ли тут тонкости?