Что на самом деле означает «когда загружен класс»? - PullRequest
16 голосов
/ 18 декабря 2011

Говорят, что статические блоки в java запускаются только один раз, когда загружается этот класс. Но что это на самом деле означает? В какой момент класс загружается JVM (виртуальной машиной Java)?

Это когда вызывается основной метод в этом классе? И все ли суперклассы одного и того же класса также загружаются, когда основной метод начинает выполнение?

Учтите, что A расширяет B, а B расширяет C. Все имеют статические блоки. Если A имеет метод main, то какова будет последовательность выполнения статических блоков?

Ответы [ 3 ]

10 голосов
/ 18 декабря 2011

Это описано в разделе Выполнение JLS. А именно:

Инициализация класса состоит из выполнения его статических инициализаторов и инициализаторов для статических полей, объявленных в классе. Инициализация интерфейса состоит из выполнения инициализаторов для полей, объявленных в интерфейсе.
Перед инициализацией класса его прямой суперкласс должен быть инициализирован , но интерфейсы, реализуемые классом, не нужно инициализировать. Аналогично, суперинтерфейсы интерфейса не должны быть инициализированы до инициализации интерфейса.

Итак, в вашем примере сначала запускается статический блок класса "topmost" (C), затем блок B, затем самый производный.

См. В этой документации подробное описание всех этапов загрузки класса.

(Классы загружаются при первом активном использовании.)

2 голосов
/ 18 декабря 2011

Я думаю, что следующий пример решит все ваши проблемы:

Перед инициализацией класса его суперклассы инициализируются, если они не были инициализированы ранее.

Таким образом, тестпрограмма:

class Super {
        static { System.out.print("Super "); }
}
class One {
        static { System.out.print("One "); }
}
class Two extends Super {
        static { System.out.print("Two "); }
}
class Test {
        public static void main(String[] args) {
                One o = null;
                Two t = new Two();
                System.out.println((Object)o == (Object)t);
        }
}

печатает:

Super Two false

Класс One никогда не инициализируется, поскольку он не используется активно и поэтому никогда не связан с.Класс Two инициализируется только после того, как его суперкласс Super был инициализирован.

Для получения более подробной информации посетите эту ссылку

Редактировать детали: Удалены путающие строки.

1 голос
/ 18 декабря 2011

Из спецификации языка Java :

Инициализация класса состоит из выполнения его статических инициализаторов и инициализаторов для статических полей (переменных класса), объявленных в классе. Инициализация интерфейса состоит из выполнения инициализаторов для объявленных там полей (констант).

Перед инициализацией класса его суперкласс должен быть инициализирован, но интерфейсы, реализуемые классом, не инициализированы. Аналогично, суперинтерфейсы интерфейса не инициализируются до инициализации интерфейса.

Процесс более подробно описан в Спецификация виртуальной машины Java .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...