Подтвердить что ты не робот

Что означает "Когда класс загружен" на самом деле означает?

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

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

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

4b9b3361

Ответ 1

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

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

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

См. документацию для подробного описания всех шагов, которые входят в загрузку класса.

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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 никогда не инициализируется, потому что он не используется активно и, следовательно, никогда не связан с ним. Класс 2 инициализируется только после инициализации суперкласса Super.

Подробнее см. ссылку

Изменить данные: удалены путаные строки.