Файл класса Java
Тип интернет-СМИ | приложение/java-vm, приложение/x-httpd-java, приложение/x-java, приложение/java, приложение/java-байт-код, приложение/x-java-класс, приложение/x-java-vm |
---|---|
Разработано | Сан Микросистемс |
Файл класса 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. Мертвое место. Когда Джерри умер, они даже построили небольшой храм в буддийском стиле. Когда мы туда ходили, мы называли это место Кафе Мертвец. Где-то по ходу дела было замечено, что это шестнадцатеричный номер. переделывал код формата файла и нуждался в паре магических чисел : одно для постоянного объектного файла и одно для классов. Я использовал CAFEDEAD для формата объектного файла и искал 4-символьные шестнадцатеричные слова, которые подходят после «CAFE». "(казалось, это хорошая тема) Я наткнулся на BABE и решил использовать ее. В то время это не казалось чем-то особенно важным и предназначенным для выбрасывания куда-либо, кроме мусорной корзины истории. Таким образом, CAFEBABE стал форматом файлов классов, а CAFEDEAD стал форматом постоянных объектов. Но возможность сохранения постоянных объектов исчезла, а вместе с ней и использование CAFEDEAD — в конечном итоге его заменили на РМИ ».
Генеральный план
[ редактировать ]Поскольку файл класса содержит элементы переменного размера и не содержит встроенных файловых смещений (или указателей), он обычно анализируется последовательно, от первого байта к концу. На самом низком уровне формат файла описывается с помощью нескольких фундаментальных типов данных:
- u1 : 8-битное целое число без знака
- u2 : 16-битное целое число без знака в порядке байтов с обратным порядком байтов.
- u4 : 32-битное целое число без знака в порядке байтов с обратным порядком байтов.
- таблица : массив элементов переменной длины некоторого типа. Количество элементов в таблице определяется предшествующим номером счетчика (счетчик — это u2), но размер таблицы в байтах можно определить только путем проверки каждого из ее элементов.
Некоторые из этих фундаментальных типов затем интерпретируются как значения более высокого уровня (например, строки или числа с плавающей запятой), в зависимости от контекста. Выравнивание слов не применяется, поэтому байты заполнения никогда не используются. Общий вид файла класса показан в следующей таблице.
Компенсация обмена | Размер | Тип или значение | Описание |
---|---|---|---|
0 | 4 байта | и1 = 0xCA шестнадцатеричный |
магическое число (CAFEBABE), используемое для идентификации файла как соответствующего формату файла класса. |
1 | и1 = 0xFE шестнадцатеричный | ||
2 | и1 = 0xBA шестнадцатеричный | ||
3 | и1 = 0xBE шестнадцатеричный | ||
4 | 2 байта | ты2 | младший номер версии используемого формата файла класса |
5 | |||
6 | 2 байта | ты2 | основной номер версии используемого формата файла класса. [3] Java SE 22 = 66 (0x42 шестнадцатеричный), |
7 | |||
8 | 2 байта | ты2 | постоянное количество пулов, количество записей в следующей таблице постоянных пулов. Это количество как минимум на единицу превышает фактическое количество записей; см. следующее обсуждение. |
9 | |||
10 | cpsize (переменная) | стол | таблица пула констант — массив записей пула констант переменного размера, содержащий такие элементы, как литеральные числа, строки и ссылки на классы или методы. Индексируется, начиная с 1, и содержит ( постоянное количество пулов - 1) общее количество записей (см. примечание). |
... | |||
... | |||
... | |||
10+ размер файла | 2 байта | ты2 | флаги доступа, битовая маска |
11+ размер файла | |||
12+ размер кадра | 2 байта | ты2 | идентифицирует этот класс, индексирует в пуле констант запись типа «Класс» |
13+ размер кадра | |||
14+ размер кадра | 2 байта | ты2 | идентифицирует суперкласс , индексирует в пуле констант запись типа «Класс» |
15+ размер страницы | |||
16+ размер кадра | 2 байта | ты2 | количество интерфейсов, количество записей в следующей таблице интерфейсов |
17+ размер изображения | |||
18+ размер изображения | размер (переменная) | стол | таблица интерфейсов: массив переменной длины постоянных индексов пула, описывающий интерфейсы, реализованные этим классом. |
... | |||
... | |||
... | |||
18+ размер + размер | 2 байта | ты2 | количество полей, количество записей в следующей таблице полей |
19+ размер + размер | |||
20+ размер + размер | fsize (переменная) | стол | таблица полей, массив полей переменной длины
каждый элемент представляет собой структуру field_info, определенную в https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5. |
... | |||
... | |||
... | |||
20+ cpsize + isize + fsize | 2 байта | ты2 | количество методов, количество записей в следующей таблице методов |
21+ cpsize + isize + fsize | |||
22+ cpsize + isize + fsize | помоги ему (переменная) | стол | таблица методов, массив методов переменной длины
каждый элемент представляет собой структуру Method_info, определенную в https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6. |
... | |||
... | |||
... | |||
22+ cpsize + isize + fsize + msize | 2 байта | ты2 | количество атрибутов, количество записей в следующей таблице атрибутов |
23+ cpsize + isize + fsize + msize | |||
24+ cpsize + isize + fsize + msize | размер (переменный) | стол | таблица атрибутов, массив атрибутов переменной длины
каждый элемент представляет собой структуру атрибута_info, определенную в https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7. |
... | |||
... | |||
... |
Представление на C-подобном языке программирования
[ редактировать ]Поскольку C не поддерживает несколько массивов переменной длины внутри структуры, приведенный ниже код не будет компилироваться и служит только демонстрацией.
struct 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 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
Постоянный пул
[ редактировать ]В таблице пула констант хранится большинство литеральных значений констант. Сюда входят такие значения, как числа всех видов, строки, имена идентификаторов, ссылки на классы и методы, а также дескрипторы типов. Все индексы или ссылки на определенные константы в таблице пула констант задаются 16-битными числами (типа u2), где значение индекса 1 относится к первой константе в таблице (значение индекса 0 недопустимо).
Из-за исторического выбора, сделанного во время разработки формата файла, количество констант в таблице пула констант на самом деле не совпадает со счетчиком пула констант, который предшествует таблице. Во-первых, таблица индексируется начиная с 1 (а не с 0), но на самом деле счетчик следует интерпретировать как максимальный индекс плюс один. [6] Кроме того, два типа констант (longs и double) занимают два последовательных слота в таблице, хотя второй такой слот представляет собой фантомный индекс, который никогда не используется напрямую.
Тип каждого элемента (константы) в пуле констант идентифицируется начальным байтовым тегом . Количество байтов, следующих за этим тегом, и их интерпретация зависят от значения тега. Допустимые типы констант и их значения тегов:
Возьмите сдачу | Дополнительные байты | Описание константы | Версия представлена |
---|---|---|---|
1 | 2+ х байт (переменная) |
Строка UTF-8 (Юникод): строка символов, перед которой стоит 16-битное число (тип u2), указывающее количество байтов в кодированной строке, которая следует сразу за ней (которое может отличаться от количества символов). Обратите внимание, что используемая кодировка на самом деле не UTF-8 , а представляет собой небольшую модификацию стандартной формы кодировки Unicode. | 1.0.2 |
3 | 4 байта | Целое число: 32-битное число , дополняющее два, со знаком в формате с обратным порядком байтов. | 1.0.2 |
4 | 4 байта | одинарной точности IEEE 754. Плавающее: 32-битное число с плавающей запятой | 1.0.2 |
5 | 8 байт | Длинное: подписанное 64-битное число с дополнением до двух в формате с обратным порядком байтов (занимает два слота в постоянной бильярдной таблице). | 1.0.2 |
6 | 8 байт | Double: 64-битное число с плавающей запятой двойной точности IEEE 754 (занимает два слота в таблице пула констант). | 1.0.2 |
7 | 2 байта | Ссылка на класс: индекс в пуле констант для строки UTF-8, содержащей полное имя класса (во внутреннем формате ) (с прямым порядком байтов). | 1.0.2 |
8 | 2 байта | Ссылка на строку: индекс в пуле констант для строки UTF-8 (также с прямым порядком байтов). | 1.0.2 |
9 | 4 байта | Ссылка на поле: два индекса в пуле констант, первый указывает на ссылку класса, второй — на дескриптор имени и типа. (с обратным порядком байтов) | 1.0.2 |
10 | 4 байта | Ссылка на метод: два индекса в пуле констант, первый указывает на ссылку класса, второй — на дескриптор имени и типа. (с обратным порядком байтов) | 1.0.2 |
11 | 4 байта | Ссылка на метод интерфейса: два индекса в пуле констант, первый указывает на ссылку класса, второй — на дескриптор имени и типа. (с обратным порядком байтов) | 1.0.2 |
12 | 4 байта | Дескриптор имени и типа: два индекса строк UTF-8 в пуле констант, первый представляет имя (идентификатор), а второй — специально закодированный дескриптор типа. | 1.0.2 |
15 | 3 байта | Дескриптор метода: эта структура используется для представления дескриптора метода и состоит из одного байта дескриптора типа, за которым следует индекс в пуле констант. [6] | 7 |
16 | 2 байта | Тип метода: эта структура используется для представления типа метода и состоит из индекса в пуле констант. [6] | 7 |
17 | 4 байта | Динамический: используется для указания динамически вычисляемой константы, создаваемой вызовом метода начальной загрузки. [6] | 11 |
18 | 4 байта | InvokeDynamic: используется инструкцией ignoredynamic для указания метода начальной загрузки, имени динамического вызова, типов аргументов и возвращаемых значений вызова и, при необходимости, последовательности дополнительных констант, называемых статическими аргументами метода начальной загрузки. [6] | 7 |
19 | 2 байта | Модуль: используется для идентификации модуля. [6] | 9 |
20 | 2 байта | Пакет: используется для идентификации пакета, экспортированного или открытого модулем. [6] | 9 |
Существует только два типа целочисленных констант: целочисленные и длинные. Другие целочисленные типы, встречающиеся в языке высокого уровня, например логические, байтовые и короткие, должны быть представлены как целочисленные константы.
Имена классов в 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
.
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ JSR 202 Обновление спецификации файла класса Java
- ^ Частное общение Джеймса Гослинга с Биллом Бамгарнером
- ^ «Глава 4. Формат файла класса» .
- ^ «Примечания к выпуску JDK 10» .
- ^ «[JDK-8148785] Обновить версию файла класса до 53 для JDK-9 — система ошибок Java» .
- ^ Jump up to: а б с д и ж г «Глава 4. Формат файла класса» .
Дальнейшее чтение
[ редактировать ]- Тим Линдхольм , Фрэнк Йеллин (1999). Спецификация виртуальной машины Java (второе изд.). Прентис Холл. ISBN 0-201-43294-3 . Проверено 13 октября 2008 г. Официальный определяющий документ виртуальной машины Java , который включает формат файла класса. И первое, и второе издания книги находятся в свободном доступе в Интернете для просмотра и/или скачивания .