структура файла класса
I. Обзор
В Java код, который понимает JVM, называется字节码
(т.е. расширение.class
файл), он не нацелен на какой-либо конкретный процессор, а только на виртуальные машины. Язык Java в определенной степени решает проблему низкой эффективности исполнения традиционных интерпретируемых языков за счет байт-кодов, и в то же время сохраняет переносимость интерпретируемых языков. Таким образом, Java-программы более эффективны для запуска, а поскольку байт-коды не являются специфическими для одной конкретной машины, Java-программы могут работать на компьютерах со многими различными операционными системами без перекомпиляции.
Такие языки, как Clojure (диалект Lisp), Groovy, Scala и т. д., работают поверх виртуальной машины Java. На рисунке ниже видно, что разные языки компилируются разными компиляторами в.class
Файлы в конечном итоге работают поверх виртуальной машины Java..class
Можно использовать двоичный формат файла.WinHexПроверять.
Можно сказать.class
Файлы являются важным связующим звеном между различными языками в виртуальной машине Java и одной из причин, почему важно поддерживать кроссплатформенность Java.
Сводная информация о файловой структуре двух классов
Согласно спецификации виртуальной машины Java, файл класса состоит из одной структуры ClassFile:
ClassFile {
u4 magic; //Class 文件的标志
u2 minor_version;//Class 的小版本号
u2 major_version;//Class 的大版本号
u2 constant_pool_count;//常量池的数量
cp_info constant_pool[constant_pool_count-1];//常量池
u2 access_flags;//Class 的访问标记
u2 this_class;//当前类
u2 super_class;//父类
u2 interfaces_count;//接口
u2 interfaces[interfaces_count];//一个类可以实现多个接口
u2 fields_count;//Class 文件的字段属性
field_info fields[fields_count];//一个类会可以有个字段
u2 methods_count;//Class 文件的方法数量
method_info methods[methods_count];//一个类可以有个多个方法
u2 attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
}
Ниже подробно описаны некоторые компоненты, задействованные в структуре файла класса.
Схема организации структуры байт-кода файла класса(Ранее сохранено в интернете, очень хорошо, первоисточник неизвестен):
2.1 Магическое число
u4 magic; //Class 文件的标志
Первые четыре байта каждого файла класса называются Magic Number, и их единственная функция —Определите, является ли этот файл файлом класса, который может быть получен виртуальной машиной..
Программистам часто нравится использовать некоторые специальные числа для представления фиксированных типов файлов или других специальных значений.
2.2 Версия файла класса
u2 minor_version;//Class 的小版本号
u2 major_version;//Class 的大版本号
Четыре байта, следующие за магическим числом, хранят номер версии файла класса: пятый и шестой —дополнительный номер версии, седьмой и восьмой естьосновной номер версии.
Виртуальная машина Java старшей версии может выполнять файл класса, сгенерированный компилятором младшей версии, но виртуальная машина Java младшей версии не может выполнять файл класса, сгенерированный компилятором старшей версии. Поэтому во время фактической разработки мы должны убедиться, что версия разработки JDK соответствует версии JDK рабочей среды.
2.3 Постоянный пул
u2 constant_pool_count;//常量池的数量
cp_info constant_pool[constant_pool_count-1];//常量池
Сразу после основных и дополнительных номеров версий идет пул констант, а количество пулов констант равно Constant_pool_count-1 (Счетчик пула констант начинает отсчет с 1. Существуют особые условия для очистки константы 0. Значение индекса 0 означает «не ссылаться ни на один элемент пула констант».).
Пул констант в основном хранит два типа констант: литералы и символические ссылки. Литералы относительно близки к константным понятиям на уровне языка Java, таким как текстовые строки, постоянные значения, объявленные как окончательные, и т. д. Символические ссылки относятся к концепции принципов компиляции. Он включает в себя следующие три типа констант:
- Полные имена классов и интерфейсов
- Имена полей и дескрипторы
- имя и дескриптор метода
Каждая константа в пуле констант представляет собой таблицу, и у этих 14 типов таблиц есть общая черта:Первый бит в начале — это бит флага типа u1, который идентифицирует тип константы, представляя, к какому типу константы принадлежит текущая константа.
тип | флаг (тэг) | описывать |
---|---|---|
CONSTANT_utf8_info | 1 | Строка в кодировке UTF-8 |
CONSTANT_Integer_info | 3 | целочисленный литерал |
CONSTANT_Float_info | 4 | литерал с плавающей запятой |
CONSTANT_Long_info | 5 | длинный буквальный |
CONSTANT_Double_info | 6 | Литерал двойной точности с плавающей запятой |
CONSTANT_Class_info | 7 | Символическая ссылка на класс или интерфейс |
CONSTANT_String_info | 8 | Литерал строкового типа |
CONSTANT_Fieldref_info | 9 | Символические ссылки на поля |
CONSTANT_Methodref_info | 10 | Символические ссылки на методы в классе |
CONSTANT_InterfaceMethodref_info | 11 | Символические ссылки на методы в интерфейсах |
CONSTANT_NameAndType_info | 12 | Символическая ссылка на поле или метод |
CONSTANT_MothodType_info | 16 | Тип метода флага |
CONSTANT_MethodHandle_info | 15 | Представляет дескриптор метода |
CONSTANT_InvokeDynamic_info | 18 | Представляет сайт вызова динамического метода |
.class
доступ к файлам возможен черезjavap -v class类名
инструкция посмотреть информацию в своем постоянном пуле (javap -v class类名-> temp.txt
: вывод результатов в файл temp.txt).
2.4 Флаги доступа
После окончания пула констант следующие два байта представляют флаг доступа, который используется для идентификации некоторой информации доступа на уровне класса или интерфейса, в том числе: является ли класс классом или интерфейсом, является ли он общедоступным или абстрактный тип, и если это класс, объявляются ли слова окончательными и так далее.
Доступ к классу и модификаторы свойств:
Мы определяем класс Employee
package top.snailclimb.bean;
public class Employee {
...
}
пройти черезjavap -v class类名
Инструкция посмотреть флаги доступа класса.
2.5 Индекс текущего класса, индекс родительского класса и коллекция индексов интерфейса
u2 this_class;//当前类
u2 super_class;//父类
u2 interfaces_count;//接口
u2 interfaces[interfaces_count];//一个雷可以实现多个接口
Индекс класса используется для определения полного имени этого класса, а индекс родительского класса используется для определения полного имени родительского класса этого класса.Из-за одиночного наследования языка Java существует только один индекс родительского класса, кромеjava.lang.Object
, все классы Java имеют суперклассы, поэтому, кромеjava.lang.Object
Кроме того, индекс родительского класса всех классов Java не равен 0.
Коллекция индексов интерфейсов используется для описания того, какие интерфейсы реализует этот класс, и эти реализованные интерфейсы будутimplents
(Если сам класс является интерфейсом, тоextends
) в коллекции индексов интерфейса слева направо.
2.6 Коллекция полевых таблиц
u2 fields_count;//Class 文件的字段的个数
field_info fields[fields_count];//一个类会可以有个字段
Информация о поле используется для описания переменных, объявленных в интерфейсе или классе. Поля включают переменные уровня класса, а также переменные экземпляра, но не локальные переменные, объявленные внутри методов.
Структура информации о поле (таблица полей):
-
access_flags:Объем поля (
public
,private
,protected
модификатор), является переменной экземпляра или переменной класса (static
модификатор), сериализуемый (переходный модификатор), изменчивость (конечный), видимость (изменчивый модификатор, следует ли принудительно читать и записывать из основной памяти). - name_index:Ссылка на константный пул, имя представляемого поля;
- descriptor_index:Ссылка на пул констант, представляющий дескрипторы полей и методов;
- attributes_count:Поле также будет иметь некоторые дополнительные атрибуты, attribute_count хранит количество атрибутов;
- attributes[attributes_count]:Храните конкретное содержимое определенного атрибута.
В приведенной выше информации каждый модификатор является логическим значением, с определенным модификатором или без него, очень удобно использовать флаг для представления. Имя поля и тип данных поля не могут быть фиксированными и могут быть описаны только путем ссылки на константы в пуле констант.
Значение access_flags поля:
2.7 Коллекция таблиц методов
u2 methods_count;//Class 文件的方法的数量
method_info methods[methods_count];//一个类可以有个多个方法
method_count представляет количество методов, а method_info представляет таблицу методов.
Описание методов в формате хранения Class file практически идентично описанию полей. Структура таблицы методов такая же, как у таблицы полей, включая, в свою очередь, флаги доступа, индексы имен, индексы дескрипторов и наборы таблиц атрибутов.
method_info (таблица методов) структура:
Значение access_flag таблицы методов:
Примечание: потому чтоvolatile
модификаторы иtransient
Модификаторы не могут модифицировать методы, поэтому флаги доступа таблицы методов не имеют этих двух соответствующих флагов, а добавляютsynchronized
,native
,abstract
и другие методы модификации ключевых слов, поэтому существует больше признаков, соответствующих этим ключевым словам.
2.8 Коллекция листа свойств
u2 attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
Файлы классов, таблицы полей и таблицы методов могут содержать собственный набор таблиц атрибутов для описания информации, специфичной для определенных сценариев. В отличие от порядка, длины и содержимого, требуемых для других элементов данных в файле Class, ограничения на коллекцию таблиц атрибутов немного слабее, и каждая таблица атрибутов больше не должна иметь строгого порядка, и до тех пор, пока она не продублировать существующее имя атрибута, любой Реализованный компилятор может записывать информацию о своих собственных атрибутах в таблицу атрибутов, а виртуальная машина Java будет игнорировать атрибуты, которые она не распознает при запуске.
Ссылаться на
- docs.Oracle.com/JavaColor/spec…
- классная оболочка.cai/articles/92…
- blog.CSDN.net/Рэндом Луис/Ах…
- «Практическая виртуальная машина Java»
Рекомендация проекта с открытым исходным кодом
Другие рекомендации автора по проектам с открытым исходным кодом:
- JavaGuide: [Изучение Java + руководство для интервью] Обложка, содержащая основные знания, которые необходимо освоить большинству Java-программистов.
- springboot-guide: Учебное пособие по Spring Boot, подходящее для начинающих и опытных разработчиков (поддержка в свободное время, добро пожаловать в совместную поддержку).
- programmer-advancement: Я думаю, некоторые хорошие привычки, которые должны быть у техников!
- spring-security-jwt-guide:Начинать с нуля! Spring Security с JWT (включая проверку авторизации) бэкэнд-часть кода.