Я хочу знать, как работает Java-компоновщик. В частности, в каком порядке он объединяет классы, интерфейсы, пакеты, методы и т.д. В jvm-исполняемый формат. Я нашел некоторую информацию здесь, но информации о порядке привязки не так много.
Как работает Java-компоновщик?
Ответ 1
Нет такой вещи, как Java-компоновщик. Однако существует концепция загрузчика классов, которая - с учетом массива java-байтовых кодов из "где-то" - может создать внутреннее представление класса, которое затем может использоваться с new
и т.д.
В этом сценарии интерфейсы представляют собой только специальные классы. Методы и поля доступны, когда класс загружен.
Ответ 2
Прежде всего: методы всегда являются частью класса. Интерфейсы - это, по сути, только специальные классы, а пакеты - всего лишь часть полного имени класса с некоторым влиянием на видимость и физическую организацию файлов классов.
Итак, вопрос сводится к: как файлы классов JVM-ссылок? Спецификация JVM, с которой вы связались, говорит:
Язык программирования Java позволяет гибкость реализации при связывании действий (и, поскольку рекурсии, загрузки), при условии, что семантика язык уважают, что класс или интерфейс полностью проверен и подготовленный до его инициализации, и что ошибки, обнаруженные во время привязки бросаются в точку в программа, в которой некоторые действия принимаются программа, которая может потребовать увязки к классу или интерфейсу, участвующим в ошибка.
Например, реализация может выберите разрешение каждой символической ссылка в классе или интерфейсе индивидуально, только когда он используется (ленивое или позднее разрешение), или разрешить их все сразу, например, пока класс проверяется (статическое разрешение). Это значит, что процесс разрешения может продолжаться, в некоторых реализациях, после класса или интерфейс был инициализирован.
Таким образом, на вопрос может быть дан ответ только для конкретной реализации JVM.
Кроме того, он никогда не должен влиять на поведение программ Java, за исключением, возможно, для точной точки, где ошибки связывания приводят к запуску экземпляров Error
.
Ответ 3
Java не связывает способ C. Принципиальная единица - это определение класса. Большая часть соответствия ссылки класса на ее определение происходит во время выполнения. Таким образом, вы можете скомпилировать класс против одной версии библиотеки, но предоставить другую версию во время выполнения. Если соответствующие сигнатуры совпадают, все будет в порядке. Там некоторые встроенные константы во время компиляции, но это об этом.
Ответ 4
Как уже отмечалось, Java-компилятор не имеет компоновщика. Однако JVM имеет фазу связывания, которая выполняется после загрузки класса. Спецификация JVM определяет его в лучшем случае:
Связывание класса или интерфейса включает в себя проверку и подготовку класс или интерфейс, его прямой суперкласс, его прямые суперинтерфейсы, и его тип элемента (если это тип массива), при необходимости. Разрешение символических ссылок в классе или интерфейсе является необязательная часть связывания.
Эта спецификация позволяет гибкость реализации в отношении того, когда (и, из-за рекурсии, загрузки) имеют место, при условии сохранения всех следующих свойств:
Класс или интерфейс полностью загружены до его привязки.
Класс или интерфейс полностью проверен и подготовлен до того, как он инициализированы.
Ошибки, обнаруженные во время связи, бросаются в точку в программе где некоторые действия принимаются программой, которая может, прямо или косвенно, требуют привязки к классу или интерфейсу, участвующим в ошибка.
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4