SlandShow
@SlandShow
70% of my body is made of movies.

Как определить порядок инициализации свойств объекта, в зависимости от различных ситуаций и контекста?

Вопрос довольно простой, как многим может показаться.

В общем:
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 работает над его базовым классом? И вообще есть ли тут тонкости?
  • Вопрос задан
  • 36 просмотров
Решения вопроса 1
  • @mipan
    переменная int до инициализации имеет значение 0;

    Инициализация:
    Статические поля класса Parent;
    Статический блок инициализации класса Parent;
    Статические поля класса Сhild;
    Статический блок инициализации класса Child;
    Нестатические поля класса Parent;
    Нестатический блок инициализации класса Parent;
    Конструктор класса Parent;
    Нестатические поля класса Сhild;
    Нестатический блок инициализации класса Сhild;
    Конструктор класса Сhild.

    Т.е. в первом варианте вы выводите значение неинициализированной переменной класса B, а во втором уже инициализованную переменную из А.
    Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы