#java #инициализация #classloader
Доброго времени суток коллеги! В литературе пишут, что при загрузке класса в первую очередь выполняется статический блок, а потом уже динамический блок и конструктор. У меня получилось написать класс так, что статический блок выполнился в последнюю очередь. public class Singleton { static Singleton st = new Singleton(); static { //статический блок System.out.println("Статический блок"); } { //анонимный блок System.out.println("Динамический блок"); } Singleton(){ //конструктор System.out.println("Конструктор"); } public static void main(String[] args) { //Пустая точка входа } } OUTPUT: Динамический блок Конструктор Статический блок Вопрос: Как объяснить наблюдаемое поведение?
Ответы
Ответ 1
Давайте по порядку посмотрим: Первым у вас объявлено статическое поле: static Singleton st = new Singleton(); Его нужно проинициализировать, соответственно вызывается конструктор: Singleton() { System.out.println("Конструктор"); } Но перед вызовом конструктора есть динамический блок инициализации, поэтому сперва инициализация объекта происходит в этом блоке, а потом уже выполняется конструктор: { //анонимный блок System.out.println("Динамический блок"); } //затем вызывается непосредственно конструктор Итак, первая строчка класса готова, статическое поле static Singleton st проинициализировано, далее уже инициализируем статический блок. Можете, на основе моего ответа предположить, что будет если в статический блок прописать ещё один вызов конструктора Singleton? Предположите, и можете попробовать затем и сравнить своё предположение. UPD. Нельзя сказать что static блок вызывается перед динамическим блоком. Они вызываются при разных условиях. Static блок вызывается после загрузки класса class loader'oм, а динамический блок вызывается при создании экземпляра класса. То есть static - инициализация класса, dynamic - инициализация экземпляра класса. И динамический блок в вашем конкретном примере вызывается во время инициализиции экземляра Singleton в первой строчке, которая static поле.Ответ 2
Инициализация статических полей и статические блоки выполняются в порядке их объявления в классе. Поскольку у вас статическое поле static Singleton st = new Singleton(); объявляется первым, то оно инициализируется в первую очередь. При инициализации поля создается объект класса, но выполнение статик блока при создании объекта пропускается, потому что его выполнение начнется только после инициализации объявленного первым статического поля. Соответственно, при инициализации данного поля игнорируется статик блок, выполняется "Динамический блок", затем конструктор класса, поле теперь проинициализировано, и, в соответствии с порядком объявления, выполняется статический блок. http://www.quizful.net/post/java-fields-initialization
Комментариев нет:
Отправить комментарий