В каком порядке различные части класса, инициализированного, когда класс загружается в JVM?

Существует хорошее объяснение здесь для.NET.

Много людей является удивлением, что ссылочные объекты на самом деле передаются значением (и в C# и в Java). Это - копия адреса стека. Это препятствует тому, чтобы метод изменился, где объект на самом деле указывает на, но все еще позволяет методу изменять значения объекта. В C# его возможное для передачи ссылки ссылкой что означает, можно измениться, где фактический объект указывает на.

6
задан Thimmayya 19 November 2009 в 06:54
поделиться

2 ответа

Как насчет JLS , в частности раздела 12.4?

1
ответ дан 17 December 2019 в 04:48
поделиться

Это может быть описано в разделе 2.17.4 JVMS 5.0 / 6

2.17.4 Инициализация

Инициализация класса состоит из:

  • выполнения его статические инициализаторы (§2.11) и
  • инициализаторы для статических полей (§2.9.2), объявленные в классе.

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

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

Класс или тип интерфейса T будет инициализирован непосредственно перед одним из следующих событий:

  • T - это класс, а экземпляр T - это создан.
  • T - это класс, и вызывается статический метод T.
  • Используется или назначается непостоянное статическое поле T. Постоянное поле - это поле, которое (явно или неявно) является как конечным, так и статическим, и которое инициализируется значением выражения константы времени компиляции. Ссылка на такое поле должна быть разрешена во время компиляции для копии значения константы времени компиляции, поэтому использование такого поля никогда не вызывает инициализацию.

Вызов определенных методов в классах библиотеки (§3.12) также вызывает инициализацию класса или интерфейса. Подробнее см. В спецификациях библиотеки классов платформы Java 2 (например, class Class и пакет java.lang.reflect).

Цель состоит в том, чтобы у типа был набор инициализаторов, которые переводят его в согласованное состояние, и что это state - это первое состояние, которое наблюдается другими классами. Статические инициализаторы и инициализаторы переменных класса выполняются в текстовом порядке и могут не ссылаться на переменные класса, объявленные в классе, объявления которых появляются в текстовом виде после использования, даже если эти переменные класса находятся в области видимости. Это ограничение предназначено для обнаружения во время компиляции большинства циклических или иным образом искаженных инициализаций.

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


Обновленная версия ] Инициализация в JVMS 8 описана в главе 5.5.

Инициализация класса или интерфейса состоит из выполнения его метода инициализации класса или интерфейса ( §2.9 ).

Класс или интерфейс могут быть инициализированы только как результат:

  • Выполнение любой из инструкций виртуальной машины Java new , Все эти инструкции ссылаются на класс прямо или косвенно через ссылку на поле или ссылку на метод.
    После выполнения новой инструкции, указанный класс или интерфейс инициализируется, если он еще не был инициализирован.
    После выполнения инструкции getstatic , putstatic или invokestatic класс или интерфейс, который объявил разрешенное поле или метод, инициализируется, если он еще не был инициализирован .
  • Первый вызов экземпляра java.lang.invoke.MethodHandle , который был результатом разрешения дескриптора метода виртуальной машиной Java ( §5.4.3.5 ) и который имеет вид 2 ( REF_getStatic ), 4 ( REF_putStatic ), 6 ( REF_invokeStatic ) или 8 ( REF_newInvokeSpecial ) .
  • Вызов определенных отражающих методов в библиотеке классов ( §2.12 ), например, в классе Class или в пакете java.lang.reflect .
  • Инициализация одного из его подклассов.
  • Его обозначение в качестве начального класса при запуске виртуальной машины Java ( §5.2 ).

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

Поскольку виртуальная машина Java является многопоточной, инициализация класса или интерфейса требует тщательной синхронизации, поскольку какой-либо другой поток может пытаться инициализировать тот же класс или интерфейс одновременно.
инициализация класса или интерфейса требует тщательной синхронизации, поскольку какой-то другой поток может одновременно пытаться инициализировать тот же класс или интерфейс.
инициализация класса или интерфейса требует тщательной синхронизации, поскольку какой-то другой поток может одновременно пытаться инициализировать тот же класс или интерфейс.
Также существует вероятность того, что инициализация класса или интерфейса может быть запрошена рекурсивно как часть инициализации этого класса или интерфейса.

Реализация виртуальной машины Java отвечает за синхронизацию и рекурсивную инициализацию с использованием следующей процедуры.
Предполагается, что объект Class уже был проверен и подготовлен, и что объект Class содержит состояние, которое указывает на одну из четырех ситуаций:

  • This Class объект проверяется и подготавливается, но не инициализируется.
  • Этот объект Class инициализируется некоторым конкретным потоком.
  • Этот объект Class полностью инициализирован и готов к использованию.
  • Этот объект Class находится в ошибочном состоянии, возможно, из-за неудачной попытки инициализации.
4
ответ дан 17 December 2019 в 04:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: