Понимание вывода javap для пула констант - PullRequest
21 голосов
/ 05 апреля 2011

Когда я запускаю javap в очень простом приложении HelloWorld, у меня возникает путаница в выводе вокруг постоянного пула.

Тестовый код

public class TestClass {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

Javap -c -verbose output (snipped)

// Header + consts 1..22 snipped
const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #22; //String hello world
   5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return
  // Debug info snipped
}

Хорошо, поэтому в строке 3 мы видим добавление константы «hello world» в стек через # 22, но const # 23 кажетсядержать фактическое значение.Я думаю, что я немного запутался с тем, что означает # (число), когда оно появляется в правой части распечатки.

Справочная страница Oracle / Sun по javap оставляет желать лучшего.

Ответы [ 3 ]

23 голосов
/ 05 апреля 2011

Все ваши class, interface, field имена и string константы входят в постоянный пул java .

Согласно спецификации VM (http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html):

constant_pool - это таблица структуры (§4.4), представляющие различные строковые константы, класс и интерфейс имена, имена полей и другие константы, которые упоминаются в структура ClassFile и ее подструктур. Формат каждого запись в таблице constant_pool указана по его первому байту «тега». Таблица constant_pool индексируется с 1 в constant_pool_count-1.

Таким образом, с точки зрения постоянного пула, что-то вроде ниже можно рассматривать как:

const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

Значение в # 22 (индекс 22) относится к типу String, а его значение - строка c с нулевым символом в конце ( Asciz ) hello world - по индексу 23.

5 голосов
/ 05 апреля 2011

Пул констант Java хранит два разных типа записей при хранении строки. Во-первых, он хранит строковый литерал как данные в кодировке UTF-8 (здесь константа # 23). Во-вторых, он также хранит строковую запись (# 22), указывающую, что содержимое константы # 23 должно использоваться для построения String. Я думаю, что причина этого в том, что JVM ассоциирует с каждым классом «пул констант времени выполнения», состоящий из динамической реализации данных констант. Для строк это может быть ссылка на встроенный объект String, содержащий заданные символы. Данные констант UTF-8 используются и в других целях, кроме строковых литералов (например, именования полей и классов), поэтому такая дополнительная косвенность кажется разумным способом для выделения проблем.

4 голосов
/ 05 апреля 2011

Пул # 22 - это объект java.lang.String.Запись # 23 - это массив символов, используемый для построения этой строки.

Java VM Spec - это «отсутствующее руководство» для javap.

...