«1. Введение

Когда мы компилируем файл .java, мы получаем отдельный файл класса с расширением .class. Файл .class состоит из нескольких разделов, одним из которых является постоянный пул.

В этом кратком руководстве мы рассмотрим детали постоянного пула. Кроме того, мы увидим, какие типы он поддерживает и как он форматирует информацию.

2. Пул констант в Java

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

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

Давайте разберемся со структурой пула констант, используя простой класс Java:

public class ConstantPool {
    
    public void sayHello() {
        System.out.println("Hello World");
    }
}

Чтобы просмотреть содержимое пула констант, нам нужно сначала скомпилировать файл, а затем запустить команду:

javap -v name.class

приведенная выше команда выдаст:

   #1 = Methodref          #6.#14         // java/lang/Object."<init>":()V
   #2 = Fieldref           #15.#16        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #17            // Hello World
   #4 = Methodref          #18.#19        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #20            // com/baeldung/jvm/ConstantPool
   #6 = Class              #21            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               sayHello
  #12 = Utf8               SourceFile
  #13 = Utf8               ConstantPool.java
  #14 = NameAndType        #7:#8          // "<init>":()V
  #15 = Class              #22            // java/lang/System
  #16 = NameAndType        #23:#24        // out:Ljava/io/PrintStream;
  #17 = Utf8               Hello World
  #18 = Class              #25            // java/io/PrintStream
  #19 = NameAndType        #26:#27        // println:(Ljava/lang/String;)V
  #20 = Utf8               com/baeldung/jvm/ConstantPool
  #21 = Utf8               java/lang/Object
  #22 = Utf8               java/lang/System
  #23 = Utf8               out
  #24 = Utf8               Ljava/io/PrintStream;
  #25 = Utf8               java/io/PrintStream
  #26 = Utf8               println
  #27 = Utf8               (Ljava/lang/String;)V

#n указывает ссылки на пул констант. №17 — это символическая ссылка на строку «Hello World», №18 — System.out, а №19 — println. Точно так же #8 указывает, что возвращаемый тип метода — void, а #20 — полное имя класса.

Важно отметить, что таблица пула констант начинается с индекса 1. Значение индекса 0 считается недопустимым индексом.

2.1. Типы

Пул констант поддерживает несколько типов:

    Integer, Float: с 32-битными константами Double, Long: с 64-битными константами String: 16-битная строковая константа, указывающая на другую запись в пуле, содержащую фактические байты Класс: содержит полное имя класса Utf8: поток байтов NameAndType: пара значений, разделенных двоеточием, первая запись представляет имя, а вторая запись указывает тип Fieldref, Methodref, InterfaceMethodref: пара, разделенная точками значений, первое значение указывает на запись Class, тогда как второе значение указывает на запись NameAndType

А как насчет других типов, таких как boolean, short и byte? Эти типы представлены как целочисленные константы в пуле.

2.2. Формат

Каждая запись в таблице подчиняется общему формату:

cp_info {
    u1 tag;
    u1 info[];
}

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

Давайте посмотрим на некоторые типы и индексы их тегов:

    Utf8: 1 Integer: 3 Float: 4 Long: 5 Double: 6 Ссылка на класс: 7 Ссылка на строку: 8

Константный пул любого класса или интерфейс создается только после завершения загрузки JVM.

3. Заключение

В этой быстрой статье мы узнали о пуле констант в JVM. Мы видели, что он содержит символические ссылки, которые используются для поиска реальных объектов. Также смотрим, как пул форматирует информацию о константах и ​​их типах.

Как всегда, фрагмент кода можно найти на Github.