Символьные ссылки в Java

В эти дни я играл с отражением Java и .class. В настоящее время я изучаю инструкцию ldc.

В спецификации JVM я нашел термин, который я не понимаю: символическая ссылка, и у меня есть следующие вопросы.

  • Что это значит?

  • Где он используется?

  • В каких случаях команда ldc загружает символическую ссылку?
  • Есть ли какой-либо код в Java, соответствующий этому действию?

Ответ 1

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

В противном случае, если запись пула постоянной времени выполнения является символической ссылкой к классу (п. 5.1), то именованный класс разрешается (п. 5.4.3.1) и ссылка на объект класса, представляющий этот класс, значение, является нажата на стек операнда.

В противном случае запись пула постоянной времени выполнения должна быть символической ссылка на тип метода или дескриптор метода (§5.1)....

Эта цитата имеет ссылку на другой раздел спецификации JVM (5.1), который описывает пул констант времени выполнения:

структуру данных во время выполнения, которая служит во многих целях таблица символов традиционной реализации языка программирования

Это означает, что пул констант времени выполнения содержит информацию о кусках класса в символической форме: в виде текстовых значений.

Итак, когда ldc задается "символическая ссылка" на класс, он присваивает индекс структуры CONSTANT_Class_info внутри пула констант. Если вы посмотрите на определение этой структуры, вы увидите, что она содержит ссылку на имя класса, также содержащуюся в пределах пула констант.

TL; DR: "символические ссылки" - это строки, которые можно использовать для извлечения фактического объекта.


Пример:

if (obj.getClass() == String.class) {
    // do something
}

Становится следующим байт-кодом:

aload_1
invokevirtual   #21; //Method java/lang/Object.getClass:()Ljava/lang/Class;
ldc     #25; //class java/lang/String
if_acmpne       20

В этом случае операция ldc относится к классу, который хранится символически. Когда JVM выполняет этот код операции, он будет использовать символическую ссылку для идентификации фактического класса в текущем загрузчике классов и вернуть ссылку на экземпляр класса.