Файл класса Java - Википедия - Java class file

Файл класса Java
РазработанSun Microsystems

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

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

История

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

Макет и структура файла

Разделы

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

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

Магический номер

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

"Мы ходили обедать в место, называемое переулком Святого Михаила. Согласно местной легенде, в глубоком темном прошлом Благодарный мертвец раньше выступали там, прежде чем они стали популярными. Это было довольно забавное место, определенно принадлежащее Grateful Dead Kinda Place. Когда Джерри умерли, они даже построили небольшую буддийскую святыню. Когда мы ходили туда, мы называли это место Cafe Dead. Где-то по ходу дела было замечено, что это шестнадцатеричное число. Я переделывал код формата файла, и мне потребовалась пара магические числа: один для постоянного объектного файла и один для классов. Я использовал CAFEDEAD для формата объектного файла, а в grepping для четырехзначных шестнадцатеричных слов, которые подходят после "КАФЕ" (это казалось хорошей темой), я выбрал BABE и решил использовать его. В то время это не казалось таким уж важным или предназначенным никуда, кроме мусора- можно истории. Таким образом, CAFEBABE стал форматом файлов классов, а CAFEDEAD - форматом постоянных объектов. Но возможность постоянного объекта исчезла, и вместе с ним исчезло использование CAFEDEAD - в конечном итоге его заменили на RMI.

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

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

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

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

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

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 шестнадцатеричный),[3]
Java SE 9 = 53 (0x35 шестнадцатеричный),[4]
Java SE 8 = 52 (0x34 шестнадцатеричный),
Java SE 7 = 51 (0x33 шестнадцатеричный),
Java SE 6.0 = 50 (0x32 шестнадцатеричный),
Java SE 5.0 = 49 (0x31 шестнадцатеричный),
JDK 1.4 = 48 (0x30 шестнадцатеричный),
JDK 1.3 = 47 (0x2F шестнадцатеричный),
JDK 1.2 = 46 (0x2E шестнадцатеричный),
JDK 1.1 = 45 (0x2D шестнадцатеричный).
Подробнее о номерах более ранних версий см. Сноску 1 на Спецификация виртуальной машины JavaTM 2-е издание

7
82 байтаu2постоянный счетчик пула, количество записей в следующей таблице постоянного пула. Это количество как минимум на единицу больше фактического количества записей; см. следующее обсуждение.
9
10cpsize (Переменная)столтаблица пула констант, массив записей пула констант переменного размера, содержащий такие элементы, как буквенные числа, строки и ссылки на классы или методы. Индексируется начиная с 1 и содержит (постоянное количество пулов - 1) общее количество записей (см. Примечание).
...
...
...
10+cpsize2 байтаu2флаги доступа, битовая маска
11+cpsize
12+cpsize2 байтаu2определяет это class, укажите в пуле констант запись типа "Class"
13+cpsize
14+cpsize2 байтаu2определяет супер class, укажите в пуле констант запись типа "Class"
15+cpsize
16+cpsize2 байтаu2количество интерфейсов, количество записей в следующей таблице интерфейсов
17+cpsize
18+cpsizeIsize (Переменная)столтаблица интерфейсов: массив переменной длины постоянных индексов пула, описывающий интерфейсы, реализованные этим классом
...
...
...
18+cpsize+Isize2 байтаu2количество полей, количество записей в следующей таблице полей
19+cpsize+Isize
20+cpsize+Isizeразмер (Переменная)столтаблица полей, массив полей переменной длины

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

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

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

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

каждый элемент представляет собой структуру 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 minor_version;      u2 major_version;   u2 constant_pool_count;        cp_info constant_pool[constant_pool_count - 1];   u2 access_flags;   u2 этот класс;   u2 super_class;   u2 interface_count;         u2 интерфейсы[interface_count];   u2 fields_count;      field_info поля[fields_count];   u2 method_count;   method_info методы[method_count];   u2 attribute_count;      attribute_info атрибуты[attribute_count];}

Постоянный бассейн

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

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

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

Байт тегаДополнительные байтыОписание константыВерсия представлена
12+Икс байты
(Переменная)
Строка UTF-8 (Unicode): символьная строка с префиксом 16-битного числа (тип u2), указывающая количество байтов в закодированной строке, которая следует непосредственно за ней (которая может отличаться от количества символов). Обратите внимание, что используемая кодировка на самом деле не UTF-8, но включает небольшую модификацию стандартной формы кодирования Unicode.1.0.2
34 байтаЦелое число: 32-битное со знаком два дополнения число в формате big-endian1.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 байтаСсылка на поле: два индекса в пуле констант, первый указывает на ссылку на класс, второй - на дескриптор имени и типа. (с прямым порядком байтов)1.0.2
104 байтаСсылка на метод: два индекса в пуле констант, первый указывает на ссылку на класс, второй - на дескриптор имени и типа. (с прямым порядком байтов)1.0.2
114 байтаСсылка на метод интерфейса: два индекса в пуле констант, первый указывает на ссылку на класс, второй - на дескриптор имени и типа. (с прямым порядком байтов)1.0.2
124 байтаДескриптор имени и типа: два индекса для строк UTF-8 в пуле констант, первый представляет имя (идентификатор), а второй - дескриптор специально закодированного типа.1.0.2
153 байтаДескриптор метода: эта структура используется для представления описателя метода и состоит из одного байта дескриптора типа, за которым следует индекс в пуле констант.[5]7
162 байтаТип метода: эта структура используется для представления типа метода и состоит из индекса в пуле констант.[5]7
174 байтаДинамический: используется для указания динамически вычисляемой константы, полученной при вызове метода начальной загрузки.[5]11
184 байтаInvokeDynamic: это используется invokedynamic инструкция для указания метода начальной загрузки, имени динамического вызова, аргументов и типов возвращаемых данных вызова и, необязательно, последовательности дополнительных констант, называемых статическими аргументами для метода начальной загрузки.[5]7
192 байтаМодуль: используется для идентификации модуля.[5]9
202 байтаПакет: используется для идентификации пакета, экспортированного или открытого модулем.[5]9

Есть только два целочисленных типа констант: целые и длинные. Другие целочисленные типы, встречающиеся в языке высокого уровня, такие как 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.

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

Рекомендации

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

  • Тим Линдхольм, Фрэнк Йеллин (1999). Спецификация виртуальной машины Java (Второе изд.). Прентис Холл. ISBN  0-201-43294-3. Получено 2008-10-13. Официальный определяющий документ Виртуальная машина Java, который включает формат файла класса. И первое, и второе издания книги находятся в свободном доступе. онлайн для просмотра и / или скачивания.