Приводит ли шаг разрешения связи классов Java ИЛИ инициализация к загрузке других разрешенных классов? - PullRequest
0 голосов
/ 07 октября 2018

Я просматривал документ спецификации JVM и JLS о механизме загрузки классов в Java.

Вот что я понимаю.

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

  2. Шаги сцепления: проверка, подготовка и разрешение

  3. Инициализация.

    Loading and linking steps.

Что я нахожу смущающим, когда на этапах «Разрешение» и «Инициализация» ссылается на класс, который еще не был загружен из источника, что произойдет?задерживает ли шаг Разрешения или Инициализации, чтобы загрузка Класса осуществлялась его родительским загрузчиком классов?

Или загрузка, Связывание и Инициализация откладываются до тех пор, пока фактический метод или код, использующий эту ссылку, не будет выполнен во время выполнения?

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

JVMS также заявляет в разделе 5.3

Если виртуальная машина Java когда-либо пытается загрузить класс C во время проверки (§5.4.1) или разрешения (§5.4.3) (но неинициализация (§5.5)), и загрузчик классов, который используется для инициирования загрузки C, генерирует экземпляр ClassNotFoundException, затем виртуальная машина Java должна выбросить экземпляр NoClassDefFoundError, причиной которого является экземпляр ClassNotFoundException.(Тонкость здесь заключается в том, что рекурсивная загрузка классов для загрузки суперклассов выполняется как часть разрешения (§5.3.5, шаг 3). Поэтому ClassNotFoundException, который возникает из-за того, что загрузчик классов не загружает суперкласс, должен быть заключен в NoClassDefFoundError.)

Так что действительно происходит рекурсия на этапе разрешения загрузки классов.

0 голосов
/ 08 октября 2018

JVMS §5.4.Связывание состояний:

Связывание класса или интерфейса включает проверку и подготовку этого класса или интерфейса, его прямого суперкласса, его прямых суперинтерфейсов и типа его элемента (если это тип массива),если необходимо.Разрешение символьных ссылок в классе или интерфейсе является необязательной частью связывания.

Поэтому, если не говорить о прямых супертипах класса, разрешение будет необязательно и может бытьdeferred.

Этот же раздел также содержит

Например, реализация виртуальной машины Java может выбрать разрешение каждой символьной ссылки в классе или интерфейсе индивидуально, когда она используется ("lazy"«или« позднее »разрешение), или разрешить их все сразу, когда класс проверяется (« нетерпеливое »или« статическое »разрешение).Это означает, что процесс разрешения может продолжаться в некоторых реализациях после инициализации класса или интерфейса.

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

На практике, в случае JSM HotSpot, некоторые классы должны быть разрешены немедленно, как суперклассы.Другие классы разрешаются при проверке кода метода, который происходит непосредственно перед первым выполнением метода для этой JVM.

Это не влияет на все классы, на которые ссылается код метода, но зависит от фактического использования типа,например, верификатор HotSpot будет разрешать типы для проверки действительности назначений по фактической иерархии типов, но пропустите этот шаг, если тип назначен самому себе или java.lang.Object, то есть где назначение всегда допустимо.Поэтому некоторые типы могут быть разрешены только при их первом фактическом использовании, например, когда они создаются с помощью метода new или static, объявленного типом.Но это зависит от тонких аспектов кода.См. Также Когда загружается класс Java? или Выдает ли JVM отсутствие отсутствующего класса?

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

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

...