Философия Java

Порядок инициализации


Внутри класса порядок инициализации определяется порядком определения переменных класса. Определения переменных может быть разбросано внутри и между определений методов, но переменные инициализируются прежде, чем любой метод может быть вызван — даже конструктор. Например:

//: c04:OrderOfInitialization.java

// Демонстрация порядка инициализации.

// Когда конструктор вызывается для создания

// объекта Tag, вы увидите сообщение:

class Tag { Tag(int marker) { System.out.println("Tag(" + marker + ")"); } }

class Card { Tag t1 = new Tag(1); // Перед конструктором

Card() { // Указывает, что мы в конструкторе:

System.out.println("Card()"); t3 = new Tag(33); // Повторная инициализация t3

} Tag t2 = new Tag(2); // После конструктора

void f() { System.out.println("f()"); } Tag t3 = new Tag(3); // В конце

}

public class OrderOfInitialization { public static void main(String[] args) { Card t = new Card(); t.f(); // Показывает завершение конструктора

} } ///:~

В Card объекты Tag определяются вперемешку для обеспечения, чтобы они все были инициализированы до входа в конструктор и до того, как что-то еще случится. Кроме того, t3 повторно инициализируется внутри конструктора. На выходе получим:

Tag(1) Tag(2) Tag(3) Card() Tag(33) f()

Таким образом, ссылка t3 инициализируется дважды, один раз до входа в конструктор, а второй при вызове конструктора. (Первый объект выбрасывается, так что он может быть позже обработан сборщиком мусора.) Сначала это может показаться не эффективно, но это гарантирует правильную инициализацию — что могло бы произойти, если бы был определен перегруженный конструктор, который бы не инициализировал t3, и не было бы инициализации “по умолчанию” для t3 в точке определения?



Содержание раздела