Файл класса 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» .
- ^ Перейти обратно: а б с д и ж г «Глава 4. Формат файла класса» .
Дальнейшее чтение
[ редактировать ]- Тим Линдхольм , Фрэнк Йеллин (1999). Спецификация виртуальной машины Java (второе изд.). Прентис Холл. ISBN 0-201-43294-3 . Проверено 13 октября 2008 г. Официальный определяющий документ виртуальной машины Java , который включает формат файла класса. И первое, и второе издания книги находятся в свободном доступе в Интернете для просмотра и/или скачивания .