Файл класса Java

Формат исполняемого файла Java
Файл класса Java
Тип интернет-СМИприложение/java-vm, приложение/x-httpd-java, приложение/x-java, приложение/java, приложение/java-байт-код, приложение/x-java-класс, приложение/x-java-vm
РазработаноSun Microsystems

Файл класса Java — это файлрасширением имени файла .class ), содержащий байт-код Java , который может быть выполнен на виртуальной машине Java (JVM) . Файл класса Java обычно создается компилятором Java из исходных файлов языка программирования Java ( файлов .java ), содержащих классы Java (в качестве альтернативы для создания файлов классов могут использоваться и другие языки JVM ). Если исходный файл содержит более одного класса, каждый класс компилируется в отдельный файл класса. Таким образом, он называется файлом .class , поскольку содержит байт-код для одного класса.

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

История

11 декабря 2006 года формат файла класса был изменен в соответствии с запросом спецификации Java (JSR) 202. [1]

Расположение и структура файла

Разделы

Структура файла класса Java состоит из 10 основных разделов:

  • Магическое число : 0xCAFEBABE
  • Версия формата файла класса : младшая и старшая версии файла класса.
  • Пул констант : Пул констант для класса
  • Флаги доступа : например, является ли класс абстрактным, статическим и т. д.
  • Этот класс : Имя текущего класса.
  • Суперкласс : Имя суперкласса
  • Интерфейсы : любые интерфейсы в классе.
  • Поля : Любые поля в классе
  • Методы : Любые методы в классе
  • Атрибуты : любые атрибуты класса (например, имя исходного файла и т. д.)

Магическое число

Файлы классов идентифицируются следующим 4- байтовым заголовкомшестнадцатеричном формате ): CA FE BA BE(первые 4 записи в таблице ниже). Историю этого магического числа объяснил Джеймс Гослинг, ссылаясь на ресторан в Пало-Альто : [2]

«Мы ходили обедать в место под названием St Michael's Alley. Согласно местной легенде, в далеком темном прошлом Grateful Dead выступали там, прежде чем добились успеха. Это было довольно необычное место, которое определенно было местом в духе Grateful Dead. Когда Джерри умер, они даже построили небольшую буддийскую святыню. Когда мы ходили туда, мы называли это место Cafe Dead. Где-то по ходу дела было замечено, что это число HEX. Я переделывал какой-то код формата файла и мне понадобилось несколько магических чисел : одно для постоянного объектного файла и одно для классов. Я использовал CAFEDEAD для формата объектного файла, и при поиске 4-символьных шестнадцатеричных слов, которые подходят после «CAFE» (казалось, это хорошая тема), я наткнулся на BABE и решил использовать его. В то время это не казалось таким уж важным или предназначенным куда-то, кроме как в мусорную корзину истории. Так CAFEBABE стал форматом файла класса, и CAFEDEAD был форматом постоянных объектов. Но возможность постоянных объектов ушла, и вместе с ней ушло и использование CAFEDEAD — в конечном итоге его заменил RMI ».

Генеральный план

Поскольку файл класса содержит элементы переменного размера и не содержит встроенных смещений файлов (или указателей), он обычно анализируется последовательно, от первого байта к концу. На самом низком уровне формат файла описывается в терминах нескольких фундаментальных типов данных:

  • u1 : беззнаковое 8-битное целое число
  • u2 : беззнаковое 16-битное целое число в порядке байтов от старшего к младшему
  • u4 : беззнаковое 32-битное целое число в порядке байтов от старшего к младшему
  • table : массив элементов переменной длины некоторого типа. Количество элементов в таблице определяется предшествующим числом счетчика (счетчик — u2), но размер таблицы в байтах можно определить только путем проверки каждого из ее элементов.

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

Смещение байтаРазмерТип или значениеОписание
04 байтаu1 =
0xCA шестнадцатеричный
магическое число (CAFEBABE), используемое для идентификации файла как соответствующего формату файла класса
1u1 =
0xFE шестнадцатеричный
2u1 =
0xBA шестнадцатеричный
3u1 =
0xBE шестнадцатеричный
42 байтау2дополнительный номер версии используемого формата файла класса
5
62 байтау2основной номер версии используемого формата файла класса. [3]

Java SE 24 = 68 (шестнадцатеричное 0x44),
Java SE 23 = 67 (шестнадцатеричное 0x43),
Java SE 22 = 66 (шестнадцатеричное 0x42),
Java SE 21 = 65 (шестнадцатеричное 0x41),
Java SE 20 = 64 (шестнадцатеричное 0x40),
Java SE 19 = 63 (шестнадцатеричное 0x3F),
Java SE 18 = 62 (шестнадцатеричное 0x3E),
Java SE 17 = 61 (шестнадцатеричное 0x3D),
Java SE 16 = 60 (шестнадцатеричное 0x3C),
Java SE 15 = 59 (шестнадцатеричное 0x3B),
Java SE 14 = 58 (шестнадцатеричное 0x3A),
Java SE 13 = 57 (шестнадцатеричное 0x39),
Java SE 12 = 56 (шестнадцатеричное 0x38),
Java SE 11 = 55 (шестнадцатеричное 0x37),
Java SE 10 = 54 (0x36 hex), [4]
Java SE 9 = 53 (0x35 hex), [5]
Java SE 8 = 52 (0x34 hex),
Java SE 7 = 51 (0x33 hex),
Java SE 6.0 = 50 (0x32 hex),
Java SE 5.0 = 49 (0x31 hex),
JDK 1.4 = 48 (0x30 hex),
JDK 1.3 = 47 (0x2F hex),
JDK 1.2 = 46 (0x2E hex),
JDK 1.1 = 45 (0x2D hex).
Подробности о более ранних номерах версий см. в сноске 1 в The JavaTM Virtual Machine Specification 2nd edition

7
82 байтау2постоянный счет пула, количество записей в следующей таблице постоянного пула. Это количество по крайней мере на единицу больше фактического количества записей; см. следующее обсуждение.
9
10cpsize (переменная)столТаблица константного пула, массив записей константного пула переменного размера, содержащий такие элементы, как литеральные числа, строки и ссылки на классы или методы. Индексируется с 1, содержит ( число константного пула - 1) общее количество записей (см. примечание).
...
...
...
10+ cpsize2 байтау2флаги доступа, битовая маска
11+ размер cp
12+ размер cp2 байтау2идентифицирует этот класс, индекс в константном пуле для записи типа «Класс»
13+ размер cp
14+ размер cp2 байтау2определяет суперкласс , индекс в константном пуле для записи типа «Класс»
15+ размер
16+ размер2 байтау2количество интерфейсов, количество записей в следующей таблице интерфейсов
17+ размер cp
18+ размер cpразмер (переменная)столтаблица интерфейсов: массив переменной длины константных индексов пула, описывающих интерфейсы, реализованные этим классом
...
...
...
18+ cpsize + isize2 байтау2количество полей, количество записей в следующей таблице полей
19+ cpsize + isize
20+ cpsize + isizefsize (переменная)столтаблица полей, массив полей переменной длины

каждый элемент представляет собой структуру field_info, определенную в https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5

...
...
...
20+ cpsize + isize + fsize2 байтау2количество методов, количество записей в следующей таблице методов
21+ cpsize + isize + fsize
22+ cpsize + isize + fsizemsize (переменная)столтаблица методов, массив методов переменной длины

каждый элемент представляет собой структуру method_info, определенную в https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6

...
...
...
22+ cpsize + isize + fsize + msize2 байтау2количество атрибутов, количество записей в следующей таблице атрибутов
23+ cpsize + isize + fsize + msize
24+ cpsize + isize + fsize + msizeразмер (переменная)столтаблица атрибутов, массив атрибутов переменной длины

каждый элемент представляет собой структуру attribute_info, определенную в https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7

...
...
...

Представление на языке программирования, подобном C

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

структура Class_File_Format { u4 magic_number ;     u2 второстепенная_версия ; u2 основная_версия ;     u2 constant_pool_count ; cp_info constant_pool [ constant_pool_count - 1 ];        u2 флаги_доступа ;  u2 этот_класс ; u2 супер_класс ;    u2 interfaces_count ; интерфейсы u2 [ interfaces_count ];      u2 fields_count ; field_info поля [ fields_count ];     u2 methods_count ; method_info методы [ methods_count ];    u2 attribute_count ; attribute_info атрибуты [ attribute_count ]; }    

Постоянный пул

Таблица константного пула — это место, где хранится большинство литеральных константных значений. Сюда входят такие значения, как числа всех видов, строки, имена идентификаторов, ссылки на классы и методы, а также дескрипторы типов. Все индексы или ссылки на конкретные константы в таблице константного пула задаются 16-битными числами (тип u2), где значение индекса 1 относится к первой константе в таблице (значение индекса 0 недопустимо).

Из-за исторических выборов, сделанных во время разработки формата файла, количество констант в таблице пула констант на самом деле не совпадает с количеством пулов констант, которое предшествует таблице. Во-первых, таблица индексируется, начиная с 1 (а не с 0), но количество фактически должно интерпретироваться как максимальный индекс плюс один. [6] Кроме того, два типа констант (long и double) занимают два последовательных слота в таблице, хотя второй такой слот является фантомным индексом, который никогда не используется напрямую.

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

Тег байтаДополнительные байтыОписание константыПредставлена ​​версия
12+ x байт
(переменная)
Строка UTF-8 (Unicode): строка символов, начинающаяся с 16-битного числа (тип u2), указывающего количество байтов в закодированной строке, которая следует сразу за ней (которое может отличаться от количества символов). Обратите внимание, что используемая кодировка на самом деле не UTF-8 , а представляет собой небольшую модификацию стандартной формы кодировки Unicode.1.0.2
34 байтаЦелое число: 32-битное число со знаком в формате дополнения до двух в формате big-endian.1.0.2
44 байтаFloat: 32-битное число с плавающей точкой одинарной точности IEEE 754.1.0.2
58 байтДлинное: знаковое 64-битное число в формате дополнения до двух в формате big-endian (занимает два слота в таблице константного пула)1.0.2
68 байтDouble: 64-битное число с плавающей точкой двойной точности IEEE 754 (занимает два слота в таблице константного пула)1.0.2
72 байтаСсылка на класс: индекс в константном пуле на строку UTF-8, содержащую полное имя класса (во внутреннем формате ) (с обратным порядком байтов)1.0.2
82 байтаСсылка на строку: индекс в константном пуле на строку UTF-8 (также с обратным порядком байтов)1.0.2
94 байтаСсылка на поле: два индекса в константном пуле, первый указывает на ссылку на класс, второй — на дескриптор имени и типа. (big-endian)1.0.2
104 байтаСсылка на метод: два индекса в константном пуле, первый указывает на ссылку на класс, второй — на дескриптор имени и типа. (big-endian)1.0.2
114 байтаСсылка на метод интерфейса: два индекса в константном пуле, первый указывает на ссылку класса, второй — на дескриптор имени и типа. (big-endian)1.0.2
124 байтаИмя и дескриптор типа: два индекса для строк UTF-8 в пуле констант, первый из которых представляет имя (идентификатор), а второй — специально закодированный дескриптор типа.1.0.2
153 байтаДескриптор метода: эта структура используется для представления дескриптора метода и состоит из одного байта дескриптора типа, за которым следует индекс в константном пуле. [6]7
162 байтаТип метода: эта структура используется для представления типа метода и состоит из индекса в константном пуле. [6]7
174 байтаДинамический: используется для указания динамически вычисляемой константы, создаваемой путем вызова метода начальной загрузки. [6]11
184 байтаInvokeDynamic: используется инструкцией invokedynamic для указания метода начальной загрузки, имени динамического вызова, типов аргумента и возвращаемого значения вызова, а также, опционально, последовательности дополнительных констант, называемых статическими аргументами метода начальной загрузки. [6]7
192 байтаМодуль: используется для идентификации модуля. [6]9
202 байтаПакет: используется для идентификации пакета, экспортированного или открытого модулем. [6]9

Существует только два типа целочисленных констант: integer и long. Другие целочисленные типы, появляющиеся в языке высокого уровня, такие как boolean, byte и short, должны быть представлены как целочисленная константа.

Имена классов в Java, если они полностью определены, традиционно разделяются точками, например, "java.lang.Object". Однако в константах ссылок на класс низкого уровня появляется внутренняя форма, которая вместо этого использует слеши, например, "java/lang/Object".

Строки Unicode, несмотря на прозвище "строка UTF-8", на самом деле не кодируются в соответствии со стандартом Unicode, хотя это похоже. Есть два отличия (см. UTF-8 для полного обсуждения). Первое заключается в том, что кодовая точка U+0000 кодируется как двухбайтовая последовательность C0 80(в шестнадцатеричном виде) вместо стандартной однобайтовой кодировки 00. Второе отличие заключается в том, что дополнительные символы (те, которые находятся вне BMP при U+10000 и выше) кодируются с использованием конструкции суррогатной пары, похожей на UTF-16 , а не напрямую кодируются с использованием UTF-8. В этом случае каждый из двух суррогатов кодируется отдельно в UTF-8. Например, U+1D11E кодируется как 6-байтовая последовательность ED A0 B4 ED B4 9E, а не как правильная 4-байтовая кодировка UTF-8 F0 9D 84 9E.

Смотрите также

Ссылки

  1. ^ Обновление спецификации файла классов Java JSR 202
  2. Личное сообщение Джеймса Гослинга Биллу Бамгарнеру
  3. ^ "Глава 4. Формат файла класса".
  4. ^ «Заметки о выпуске JDK 10».
  5. ^ "[JDK-8148785] Обновление версии файла класса до 53 для JDK-9 - Java Bug System".
  6. ^ abcdefg "Глава 4. Формат файла класса".

Дальнейшее чтение

  • Тим Линдхольм, Фрэнк Йеллин (1999). Спецификация виртуальной машины Java (второе издание). Prentice Hall. ISBN 0-201-43294-3. Получено 13 октября 2008 г.Официальный определяющий документ Java Virtual Machine , включающий формат файла класса. Первое и второе издание книги доступны бесплатно в Интернете для просмотра и/или загрузки.
Получено с "https://en.wikipedia.org/w/index.php?title=Java_class_file&oldid=1254751149"