Введение
Java-код компилируется в файл класса компилятором java, а затем загружается и выполняется с помощью jvm.JVM скрывает детали выполнения базовой системы платформы, поэтому он может выполнять компиляцию один раз и выполнение в любом месте.
Скомпилированный файл класса представляет собой файл двоичного потока, такой как следующий класс:
public class ServiceResult<T> {
private static final int SUCCESS_CODE = 200;
private static final String SUCCESS_MESSAGE = "Success";
private int code;
private String message;
private T data;
public ServiceResult(T data) {
this.code = SUCCESS_CODE;
this.message = SUCCESS_MESSAGE;
this.data = data;
}
public ServiceResult(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public boolean isSuccess() {
return code == SUCCESS_CODE;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public T getData() {
return data;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ServiceResult{");
sb.append("code=").append(code);
sb.append(", message='").append(message).append('\'');
sb.append(", data=").append(data);
sb.append('}');
return sb.toString();
}
}
Скомпилированный класс открывается в шестнадцатеричном формате следующим образом:
Примечание. Файл класса представлен в байтах (8 бит), а u1, u2, u4 и u8 используются для представления 1 байта, 2 байтов, 4 байтов и 8 байтов чисел без знака в форме Big-edian, то есть , сначала старший байт.
Структура класса
Если бинарный файл класса описывает свою логическую структуру в виде C-подобной языковой структуры, она будет такой, как показано на следующем рисунке:
Как видно из рисунка, файл класса в основном содержит магию, минорную версию, мажорную версию, постоянный пул, флаги доступа, this_class, суперкласс, интерфейсы, поля, методы, атрибуты 11 частей, каждая часть компактно склеена вместе , Здесь нет разделения разделителями, и каждая структура описана отдельно ниже.
Прежде чем приступить к представлению каждой структуры, необходимо пояснить, что эта статья основана на jvm1.8.
Эта статья немного длинная,здесьТипографика выглядит более удобной
1. magic
Магическое число:Беззнаковое число из 4 байтов с фиксированным значением 0xCAFEBABE, используемое для идентификации файла как файла класса.
2. minor version
Второстепенный номер версии:Беззнаковое число, занимающее два байта, в диапазоне от 0 до 65535. Вместе с мажорной версией указывает версию текущего файла класса.jvm может быть совместим вперед с предыдущей версией, но не совместим обратно, то есть jdk7 виртуальная машина не может запустить компиляцию jdk8.класс
3. major version
Номер основной версии:Число без знака, занимающее два байта. Основной номер версии, используемый jdk1.1, — 45, и каждая основная версия увеличивается на 1. Например, jdk1.8 — 52.
4. constant pool
Постоянный пул:Пул констант — очень важная часть класса, в нем хранятся не только константы, определенные в классе, но и различные метаданные в файле класса, включая некоторые строки, имена классов, имена интерфейсов, имена полей и методы. , и т. д., на его функцию следует ссылаться, часть пула констант сначала имеет два байта u2 для записи количества содержащихся в нем констант.
PS1: Константный пул представляет собой массив констант. Его нижний индекс начинается с 1, то есть эффективный размер - это Constant_pool_count-1, а 0-й элемент недействителен. Некоторые структуры могут использовать индекс 0, чтобы указать, что нет ссылки на постоянный.
PS2: дизайн пула констант эффективно уменьшает размер файла класса, подумайте о тех именах классов, которые используются повторно, строка теперь должна хранить только одну копию, а в качестве ссылки нужно использовать только u2 для сохранения своего индекса в постоянный бассейн просто отлично
Поскольку каждая константа имеет определенный тип для представления различных значений, невозможно проанализировать конкретный элемент константы, просто зная количество констант, поэтому первый байт u1 каждой константы определяется для представления значения константы. тег, а затем его можно разобрать в соответствии со структурой хранения константы типа.
Постоянные теги включают CONSTANT_Utf8, CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long, CONSTANT_Double, CONSTANT_Class, CONSTANT_String, CONSTANT_Fieldref, CONSTANT_Methodref, CONSTANT_InterfaceMethodref, CONSTANT_NameAndType, CONSTANT_MethodHandle, CONSTANT_MethodType, CONSTANT_InvokeDynamic.
4.1 CONSTANT_Utf8_info
Самая основная константа в пуле констант, используемая для сохранения строки в кодировке utf8, такой как строка константы, имя класса, имя поля, имя метода и т. д. Значение является ссылкой (индексом) на нее.
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
tag=1, length представляет длину строки в байтах, например, length=20 означает, что следующие 20 байтов представляют собой строку в кодировке utf8.
Вот два дополнительных момента:
-
java использует переменную кодировку utf8: символы ASCII ('
\u0001
' ~ '\u007F
', то есть 1~127) представлен 1 байтом, ноль ('\u0000
')а также '\u0080
' прибыть '\u07FF
' Символы между ними представлены 2 байтами, '\u0800
' прибыть '\uFFFF
Символы между ' представлены 3 байтами.Наоборот, если старший бит байта равен 0, это однобайтовый символ.
Старшие 3 бита прочитанного байта
110
Это двухбайтовый символ, за которым следует еще 1 байт.Старшие 4 бита прочитанного байта
1110
, представляет собой трехбайтовый символ, за которым следуют еще 2 байта.О том, как декодировать, вы можете проверить в официальной документации.В java нам нужно использовать только
new String(bytes, StandardCharset.UTF8)
чтобы получить декодированную строку -
длина представлена как u2 (0-65535), тогда максимальная длина строки, представленной им, равна 65535
4.2 CONSTANT_Integer_info
CONSTANT_Integer_info {
u1 tag;
u4 bytes;
}
int, tag=3, следующие 4 байта представляют собой значение int. Добавьте следующие пункты о CONSTANT_Integer:
-
с обратным порядком байтов, сначала старший байт, то же верно и ниже
Если вы разберете его самостоятельно, это будет выглядеть так:
int value = 0; byte[] data = new byte[4]; is.read(data); value = (value | (((int) data[0]) & 0xff)) << Byte.SIZE * 3; value = (value | (((int) data[1]) & 0xff)) << Byte.SIZE * 2; value = (value | (((int) data[2]) & 0xff)) << Byte.SIZE; value = (value | (((int) data[3]) & 0xff));
Мы можем прочитать значение int, используя метод readInt() класса DataInputStream.
-
Джава
short
,char
,byte
,boolean
Используйте int для представления, логический массив представлен массивом байтов (1 байт представляет 1 логический элемент)
4.3 CONSTANT_Float_info
CONSTANT_Float_info {
u1 tag;
u4 bytes;
}
float число с плавающей запятой, tag=4, следующие 4 байта представляют его значение, которое определено стандартом IEEE 754. Значение с плавающей запятой можно прочитать с помощью метода readFloat() класса DataInputStream.
4.4 CONSTANT_Long_info
CONSTANT_Long_info {
u1 tag;
u4 high_bytes;
u4 low_bytes;
}
tag=5, long integer, long и double хранятся в классе двумя частями (старшие 4 байта, позиция 4 байта). Значение с плавающей запятой можно прочитать с помощью метода readLong() класса DataInputStream.
4.5 CONSTANT_Double_info
CONSTANT_Double_info {
u1 tag;
u4 high_bytes;
u4 low_bytes;
}
tag=6, число двойной точности с плавающей запятой, определенное стандартом IEEE 754. Хранилище такое же, как CONSTANT_Long.
4.6 CONSTANT_Class_info
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}
tag=7, указывающий на класс или интерфейс, обратите внимание, что это не тип поля или тип параметра и тип возвращаемого значения метода. name_index — это постоянный индекс пула, и константа в этом индексе должна бытьCONSTANT_Utf8_info
4.7 CONSTANT_String_info
CONSTANT_String_info {
u1 tag;
u2 string_index;
}
tag=8, что указывает на константную строку, string_index — это индекс пула констант, константа по этому индексу должна бытьCONSTANT_Utf8_info
, в котором хранится значение строки
4.8 CONSTANT_Fieldref_info
CONSTANT_Fieldref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
tag=9, указывает информацию о ссылочном поле, включая статическое поле и поле экземпляра.
class_index — это индекс константы типа CONSTANT_Class_info (класс/интерфейс) в пуле констант, указывающий класс, к которому принадлежит поле. name_and_type_index — постоянный индекс типа CONSTANT_NameAndType_info (см. ниже) в пуле констант, указывающий имя и тип поля.
Объясните ссылку на поле, включая следующий метод, ссылка на метод интерфейса такая же:
- Начиная с этой статьи класс ServiceResult
code
Возьмем поле в качестве примера, код используется в нескольких методах.По сравнению с сохранением нескольких копий информации о поле, очевидно, более целесообразно сохранить одну копию информации о поле в пуле констант, а затем сохранить ее индекс в других местах, где Это использовано. - CONSTANT_Fieldref_info предназначена для извлечения полей (которые могут относиться к этому классу или внешним классам), на которые есть ссылки в коде, в константы, которые аналогичны описанным ниже.
field_info
не путай
4.9 CONSTANT_Methodref_info
CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
tag=10, что означает информацию об эталонном методе, включая статический метод и метод экземпляра.
class_index — это индекс константы типа CONSTANT_Class_info (здесь может быть только класс) в пуле констант, указывающий класс, к которому принадлежит метод. name_and_type_index — постоянный индекс типа CONSTANT_NameAndType_info в пуле констант, указывающий имя и параметры метода, а также информацию о возвращаемом значении.
4.10 CONSTANT_InterfaceMethodref_info
CONSTANT_InterfaceMethodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
tag=11, указывающий информацию о методе интерфейса.
class_index — это индекс константы типа CONSTANT_Class_info (здесь может быть только интерфейс) в пуле констант, указывающий интерфейс, которому принадлежит метод. name_and_type_index совпадает с CONSTANT_Methodref_info.
4.11 CONSTANT_NameAndType_info
CONSTANT_NameAndType_info {
u1 tag;
u2 name_index;
u2 descriptor_index;
}
tag=12, который хранит имя, тип и другую информацию о поле или методе.Видно, что это снова две ссылки. name_index указывает на CONSTANT_Utf8_info, указывающее поле или метод.неполное имя. descriptor_index также указывает на CONSTANT_Utf8_info, которая представляет информацию описания этого поля/метода.
Descriptor
Дескриптор хранится в виде строки CONSTANT_Utf8_info.
-
дескриптор поля (FieldType), FieldType может быть примитивным типом:
B(byte)
C(char)
D(double)
F(float)
I(int)
J(long)
S(short)
Z(boolean)
, тип объекта: L+ полное имя класса, тип массива: [+ тип элементаint a; // I Integer b; //Ljava/lang/Integer double[] c; //[D double[][] d; //[[D Object[] e; //[Ljava/lang/Object Object[][][] f; //[[[Ljava/lang/Object
-
дескриптор метода (MethodDescriptor), формат MethodDescriptor
(参数类型)返回类型
/** * 描述符:(IDLjava/lang/Thread;)Ljava/lang/Object; */ Object m(int i, double d, Thread t) {...}
4.12 CONSTANT_MethodHandle_info
CONSTANT_MethodHandle_info {
u1 tag;
u1 reference_kind;
u2 reference_index;
}
tag=15, дескриптор метода, такой как получение статического поля класса, поля экземпляра, вызов метода, конструктора и т. д., будет преобразован в ссылку на дескриптор.
-
reference_kind
Kind Description Interpretation 1 REF_getField
getfield C.f:T
2 REF_getStatic
getstatic C.f:T
3 REF_putField
putfield C.f:T
4 REF_putStatic
putstatic C.f:T
5 REF_invokeVirtual
invokevirtual C.m:(A*)T
6 REF_invokeStatic
invokestatic C.m:(A*)T
7 REF_invokeSpecial
invokespecial C.m:(A*)T
8 REF_newInvokeSpecial
new C; dup; invokespecial C.<init>:(A*)V
9 REF_invokeInterface
invokeinterface C.m:(A*)T
f: поле, m: метод, : конструктор экземпляра
-
reference_index
- Для Kind=1, 2, 3, 4 reference_index ссылается на CONSTANT_Fieldref_info
- Для типов = 5, 6, 7, 8, reference_index ссылается на CONSTANT_Methodref_info.
- Для Kind=9 reference_index ссылается на CONSTANT_InterfaceMethodref_info.
4.13 CONSTANT_MethodType_info
CONSTANT_MethodType_info {
u1 tag;
u2 descriptor_index;
}
tag=16, описывающий тип метода. descriptor_index относится к CONSTANT_Utf8_info, представляющему дескриптор метода
4.14 CONSTANT_InvokeDynamic_info
CONSTANT_InvokeDynamic_info {
u1 tag;
u2 bootstrap_method_attr_index;
u2 name_and_type_index;
}
tag=18, справочная информация об инструкциях динамического вызова invokedynamic.
- bootstrap_method_attr_index, индекс массива bootstrap_methods[] в атрибуте BootstrapMethods, каждый метод начальной загрузки ссылается на CONSTANT_MethodHandle_info
- name_and_type_index, ссылающийся на константу CONSTANT_NameAndType_info
5. access flags
Флаги доступа представляют информацию об управлении доступом и оформлении для классов, интерфейсов, полей и методов.
Access Flag(u2) | Value | Объект действия |
---|---|---|
ACC_PUBLIC | 0x0001 | class, inner, field, method |
ACC_PRIVATE | 0x0002 | inner, field, method |
ACC_PROTECTED | 0x0004 | inner, field, method |
ACC_STATIC | 0x0008 | inner, field, method |
ACC_FINAL | 0x0010 | class, inner, field, method |
ACC_SUPER | 0x0020 | class |
ACC_SYNCHRONIZED | 0x0020 | method |
ACC_VOLATILE | 0x0040 | field |
ACC_BRIDGE | 0x0040 | method |
ACC_TRANSIENT | 0x0080 | field |
ACC_VARARGS | 0x0080 | method |
ACC_NATIVE | 0x0100 | method |
ACC_INTERFACE | 0x0200 | class, inner |
ACC_ABSTRACT | 0x0400 | class, inner, method |
ACC_STRICT | 0x0800 | method |
ACC_SYNTHETIC | 0x1000 | class, inner, field, method |
ACC_ANNOTATION | 0x2000 | class, inner |
ACC_ENUM | 0x4000 | class, inner, field |
Большинство из них можно увидеть по названию, а также добавлены следующие пункты:
- ACC_SUPER: метод суперкласса для вызова специальной инструкции, требующей специальной обработки.
- ACC_BRIDGE: флаг метода моста, метод с этим флагом также имеет флаг ACC_SYNTHETIC
- ACC_STRICT: strictfp, строгий формат с плавающей запятой, метод использует FP-строгий формат с плавающей запятой.
- ACC_SYNTHETIC: флаг генерируется компилятором, а не исходным кодом.
6. this class
Текущий класс или интерфейс, указывающий на константу CONSTANT_Class_info, из которой может быть разрешено полное имя текущего класса. уровень имени пакета/
разделить вместо.
,какjava/lang/Object
.
7. super class
Прямой индекс родительского класса текущего класса, указывающий на константу CONSTANT_Class_info, super_class=0, когда прямого родительского класса нет.
8. interfaces
Во-первых, используйте u2, чтобы указать количество n прямых родительских интерфейсов текущего класса или интерфейса. Массив, состоящий из n u2, является индексом этих родительских интерфейсов в пуле констант, типом является CONSTANT_Class_info, слева направо в порядке объявления.
9. fields
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
field_info сохраняет информацию о полях текущего класса. Очень просто, большинство из них упоминалось ранее, а атрибуты объясняются в Разделе 11 ниже. Следует отметить, что поля содержат только поля текущего класса, например, поле c внутреннего класса B класса A относится к классу A$B.
10. methods
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
Сохраните информацию о методе текущего класса, как и field_info
11. attributes
Таблица атрибутов: атрибуты существуют сClassFile
, field_info
, method_info
Кроме того, атрибут Code также содержит информацию о вложенных атрибутах.Атрибуты используются для описания такой информации, как коды инструкций, исключения, аннотации, дженерики и т. д. В JLS8 предопределены 23 атрибута, каждый из которых имеет различную структуру (переменную длину), но может абстрагироваться в следующую общую структуру.
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info[attribute_length];
}
attribute_name_index: это индекс имени атрибута в пуле констант, по которому текущий атрибут может быть определен, к какому конкретному типу он принадлежит, например, «Code» означает, что в данный момент это Code_attribute
attribute_length: Указывает, сколько байтов составляет информация о содержимом атрибута. Java позволяет настраивать новые атрибуты. Если jvm не знает этого, он будет напрямую читать байты attribute_length в соответствии с общей структурой.
23 атрибута можно разделить на 3 группы в зависимости от их функций:
- Используется переводом jvm: ConstantValue, Code, StackMapTable, Exceptions, BootstrapMethods.
- Используется анализом библиотеки классов Java: InnerClasses, EnclosingMethod, Synthetic, Signature, RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations/RuntimeInvisibleParameterAnnotations, RuntimeVisibleTypeAnnotations/RuntimeInvisibleTypeAnnotations, AnnotationDefault, MethodParameters
- Ни синтаксический анализ jvm, ни синтаксический анализ библиотеки классов java не требуется для таких сценариев, как инструменты отладки: SourceFile, SourceDebugExtension, LineNumberTable, LocalVariableTable, LocalVariableTypeTable, Deprecated
Примечание: позже я объясню, как анализировать класс, поэтому в этой статье дается лишь краткое введение в структуру и функции каждого атрибута.
11.1 ConstantValue
ConstantValue_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 constantvalue_index;
}
Существует в field_info и представляет постоянное значение, напримерprivate final int x = 5
середина5
. Значением, на которое ссылается attribute_name_index, является «ConstantValue», attribute_length фиксируется равным 2, а Constantvalue_index следующих двух байтов является индексом постоянного значения в пуле констант, который является одним из CONSTANT_Long, CONSTANT_Float, CONSTANT_Double, CONSTANT_Integer и CONSTANT_String. .
11.2 Code
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
Описывает инструкции байт-кода после компиляции тела метода. Метод, описанный ранееmethod_info
структура, а информация о теле метода существует в атрибуте кода в его таблице атрибутов. Если это абстрактный метод, у него нет этого свойства.
Я говорил об общей структуре атрибутов ранееattribute_info
уже сказал когдаattribute_name_index
, attribute_length
, который доступен для каждого атрибута, и не будет объясняться ниже, будут представлены только другие части.
-
max_stack , максимальная глубина стека операндов, используемая для выделения размера стека
-
max_locals — максимальная емкость таблицы локальных переменных в кадре стека методов, в которой хранятся локальные переменные, параметры методов, параметры исключений и т. д. Возьмите слот в качестве единицы, выделите 1 слот для переменных в пределах 32 бит и выделите 2 слота для переменных больше 32 бит. Например, long и double выделяют 2 слота. Обратите внимание, что объекты хранятся как ссылки. Также обратите внимание, что для методов экземпляра указатель объекта this передается по умолчанию, поэтому минимальное значение max_locals в настоящее время равно 1.
-
code[code_length], хранит список инструкций байт-кода, каждая инструкция байт-кода представляет собой байт, так что 8 бит может представлять до 256 различных инструкций.Следует отметить, что этот массив байт-потока хранит не все инструкции, некоторые инструкции. соответствующие операнды, пропустить соответствующие n-байтовые операнды, а затем следующую инструкцию.Я продемонстрирую подробности в другой статье.
-
exception_table[exception_table_length], таблица исключений метода, обратите внимание, что это не исключение, вызванное объявлением метода, а исключение try-catch, и исключение каждого улова является элементом таблицы exception_table.
- catch_type, тип перехватываемого исключения, указывает на константу CONSTANT_Class_info.
- start_pc, смещение инструкции байт-кода относительно начала метода, эквивалентно индексу в code[code_length]
- end_pc, смещение инструкции байт-кода относительно начала метода, эквивалентное индексу в code[code_length]
- handler_pc, смещение инструкции байт-кода относительно начала метода, эквивалентное индексу в code[code_length]
Эти элементы означают, что если в интервале [start_pc, end_pc) возникает исключение типа catch_type или его подкласса (catch_type=0 означает перехватывать любое исключение), перейти к инструкции в handler_pc для продолжения выполнения.
Добавьте три пункта:
1) Способ использования инструкций в блоке finaly состоит в том, чтобы иметь избыточную копию в каждой ветви кода.
2) Для исключений, которые не отображаются пойманными, затем передайте
athrow
Инструкция продолжает кидать3) Хотя длина инструкции code_length равна u4, start_pc, end_pc и handler_pc являются только 2-байтовыми беззнаковыми числами u2, а максимальный диапазон представления составляет всего 65535, поэтому метод может иметь только до 65535 инструкций (каждая инструкция не имеет операции). количество)
-
attribute[attributes_count], список вложенных атрибутов
11.3 StackMapTable
StackMapTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_entries;
stack_map_frame entries[number_of_entries];
}
Как упоминалось выше, Code_attribute также может содержать таблицы атрибутов, StackMapTable находится в таблице атрибутов атрибутов Code и добавляется для проверки вывода типа на этапе проверки байт-кода jvm.
11.4 Exceptions
Exceptions_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_exceptions;
u2 exception_index_table[number_of_exceptions];
}
выразить черезthrows
Объявленные исключения, которые могут быть выброшены, структура очень проста.Каждый элемент exception_index_table u2 указывает на константу CONSTANT_Class_info
11.5 BootstrapMethods
BootstrapMethods_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 num_bootstrap_methods;
{ u2 bootstrap_method_ref;
u2 num_bootstrap_arguments;
u2 bootstrap_arguments[num_bootstrap_arguments];
} bootstrap_methods[num_bootstrap_methods];
}
Находится в ClassFile, содержит метод начальной загрузки, на который ссылается инструкция invokedynamic.
- bootstrap_method_ref, ссылается на константу CONSTANT_MethodHandle_info, reference_kind MethodHandle должен быть REF_invokeStatic или REF_newInvokeSpecial.
- num_bootstrap_arguments, список параметров метода начальной загрузки, каждый элемент в массиве является
CONSTANT_String_info
,CONSTANT_Class_info
,CONSTANT_Integer_info
,CONSTANT_Long_info
,CONSTANT_Float_info
,CONSTANT_Double_info
,CONSTANT_MethodHandle_info
, orCONSTANT_MethodType_info
Цитировать
11.6 InnerClasses
InnerClasses_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_classes;
{ u2 inner_class_info_index;
u2 outer_class_info_index;
u2 inner_name_index;
u2 inner_class_access_flags;
} classes[number_of_classes];
}
Запишите информацию о внутреннем классе, классы — это список внутренних классов текущего класса, где inner_class_info_index, external_class_info_index указывают на константы типа CONSTANT_Class, представляющие ссылку на информацию о внутреннем классе и внешнем классе соответственно, inner_name_index — это ссылка на имя внутреннего класса (CONSTANT_Utf8_info ), равный 0, означает анонимный внутренний класс, inner_class_access_flags — это флаг доступа к внутреннему классу, такой же, как и access_flags
11.7 EnclosingMethod
EnclosingMethod_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 class_index;
u2 method_index;
}
Он находится в структуре ClassFile и хранит информацию о локальном или анонимном классе.
- class_index, ссылка на класс, который непосредственно его содержит, ссылается на константу CONSTANT_Class_info, представляющую самый внутренний класс, содержащий текущее объявление класса.
- method_index относится к константе CONSTANT_NameAndType_info, которая непосредственно содержит имя и тип метода локального класса и анонимного класса.
11.8 Synthetic
Synthetic_attribute {
u2 attribute_name_index;
u4 attribute_length;
}
Отмечает, генерируются ли компилятором классы, методы и поля, что является синонимом ACC_SYNTHETIC, attribute_length=0, и наличие этого атрибута указывает на true.
11.9 Signature
Signature_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 signature_index;
}
Существует в таблице свойств классов, методов и полей и используется для хранения общей информации о классах, методах и полях (переменные типа — переменные типа, параметризованные типы — параметризованные типы).
О дженериках можно обратиться кздесь
- signal_index, который ссылается на константу CONSTANT_Utf8_info, представляющую подпись
11.10 RuntimeVisibleAnnotations
RuntimeVisibleAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 num_annotations;
annotation annotations[num_annotations];
}
Существует в классах, методах, полях и хранит информацию об аннотациях, видимую во время выполнения (RetentionPolicy.RUNTIME), которую можно получить с помощью API отражения.здесь
Структура аннотации хранит информацию о паре имени аннотации и значения элемента.Подробности см. в официальной документации или в моей статье о разборе классов позже.
11.11 RuntimeInvisibleAnnotations
RuntimeInvisibleAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 num_annotations;
annotation annotations[num_annotations];
}
Имеет ту же структуру, что и RuntimeVisibleAnnotations, но является невидимым, то есть не может быть получен API отражения.В настоящее время jvm игнорирует это свойство.
11.12 RuntimeVisibleParameterAnnotations
RuntimeVisibleParameterAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u1 num_parameters;
{ u2 num_annotations;
annotation annotations[num_annotations];
} parameter_annotations[num_parameters];
}
Он существует в таблице атрибутов method_info и хранит информацию об аннотациях параметров метода, видимых во время выполнения.По сравнению с RuntimeVisibleAnnotations обнаружено, что RuntimeVisibleParameterAnnotations хранит аннотации каждого параметра в списке параметров метода (эквивалентно набору RuntimeVisibleParameterAnnotations). , дескрипторы порядка и метода Параметры в том же порядке
11.13 RuntimeInvisibleParameterAnnotations
RuntimeInvisibleParameterAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u1 num_parameters;
{ u2 num_annotations;
annotation annotations[num_annotations];
} parameter_annotations[num_parameters];
}
я не хочу больше говорить
11.14 RuntimeVisibleTypeAnnotations
RuntimeVisibleTypeAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 num_annotations;
type_annotation annotations[num_annotations];
}
Существовать в таблице атрибутов class_file, method_info, field_info, code, new in java8. JLS8 добавляет два новых типа элементов (ElementType.TYPE_PARAMETER, ElementType.TYPE_USE), и соответствующие атрибуты аннотаций, используемые для описания, также были изменены соответствующим образом. С помощью этого атрибута type_annotation хранит информацию аннотаций и свой функциональный объект.
11.15 RuntimeInvisibleTypeAnnotations
RuntimeInvisibleTypeAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 num_annotations;
type_annotation annotations[num_annotations];
}
немного. . .
11.16 AnnotationDefault
AnnotationDefault_attribute {
u2 attribute_name_index;
u4 attribute_length;
element_value default_value;
}
Существовать вmethod_info
лист свойств, в котором записаны значения по умолчанию для элементов аннотации
11.17 MethodParameters
MethodParameters_attribute {
u2 attribute_name_index;
u4 attribute_length;
u1 parameters_count;
{ u2 name_index;
u2 access_flags;
} parameters[parameters_count];
}
Существовать вmethod_info
Таблица атрибутов, информация о параметрах метода записи, имя параметра name_index, флаги доступа имеют ACC_FINAL, ACC_SYNTHETIC, ACC_MANDATED
11.18 SourceFile
SourceFile_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 sourcefile_index;
}
В таблице атрибутов class_file запишите имя файла, сгенерировавшего файл. Стек исключений может отображать эту информацию, которая обычно совпадает с именем класса, но не с внутренним классом. Это необязательный атрибут, который означает, что компилятор не обязан генерировать эту информацию.
11.19 SourceDebugExtension
SourceDebugExtension_attribute {
u2 attribute_name_index;
u4 attribute_length;
u1 debug_extension[attribute_length];
}
Существует в структуре класса, необязателен, сохраняет расширенную отладочную информацию для языков, отличных от Java.debug_extension
Массив является индексом в CONSTAN_Utf8_info.
11.20 LineNumberTable
LineNumberTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 line_number_table_length;
{ u2 start_pc;
u2 line_number;
} line_number_table[line_number_table_length];
}
В таблице атрибутов кода хранится отношение сопоставления между номером строки исходного кода и смещением байт-кода (первая инструкция метода), смещение байт-кода start_pc, номер строки исходного кода line_number, необязательный.
Вопрос: Как распечатать номер строки исходного кода ошибки в стеке ошибок? Как поддерживать отладку точки останова в исходном коде?
11.21 LocalVariableTable
LocalVariableTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 local_variable_table_length;
{ u2 start_pc;
u2 length;
u2 name_index;
u2 descriptor_index;
u2 index;
} local_variable_table[local_variable_table_length];
}
В таблице атрибутов кода сохраняется сопоставление между переменными таблицы локальных переменных в кадре стека и переменными, определенными в исходном коде, которое может быть связано с именем переменной переменной таблицы локальных переменных в исходном коде. при разборе атрибут кода и т.п. необязателен.
11.22 LocalVariableTypeTable
LocalVariableTypeTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 local_variable_type_table_length;
{ u2 start_pc;
u2 length;
u2 name_index;
u2 signature_index;
u2 index;
} local_variable_type_table[local_variable_type_table_length];
}
В таблице атрибутов кода, подобно LocalVariableTable, signal_index также относится кCONSTANT_Utf8_info
Константы, соответствующие переменным, содержащим дженерики, будут храниться как в LocalVariableTable, так и в LocalVariableTypeTable.
11.23 Deprecated
Deprecated_attribute {
u2 attribute_name_index;
u4 attribute_length;
}
Класс, метод, маркер окончания срока действия поля, без дополнительной информации, attribute_length=0, если этот атрибут появляется, значит, добавлена аннотация @deprecated
над!Если вы считаете, что написать это нормально, пожалуйста, поставьте лайк, чтобы поощрить это!
Следующее уведомление: начните писать программу, которая анализирует файлы классов (байт-код)
Обратите внимание на WeChat, вас ждет еще больше интересного