[Получить интервью JVM] Интервьюер: расскажите о понимании файловой структуры класса JVM.

Java

структура файла класса

I. Обзор

В Java код, который понимает JVM, называется字节码(т.е. расширение.classфайл), он не нацелен на какой-либо конкретный процессор, а только на виртуальные машины. Язык Java в определенной степени решает проблему низкой эффективности исполнения традиционных интерпретируемых языков за счет байт-кодов, и в то же время сохраняет переносимость интерпретируемых языков. Таким образом, Java-программы более эффективны для запуска, а поскольку байт-коды не являются специфическими для одной конкретной машины, Java-программы могут работать на компьютерах со многими различными операционными системами без перекомпиляции.

Такие языки, как Clojure (диалект Lisp), Groovy, Scala и т. д., работают поверх виртуальной машины Java. На рисунке ниже видно, что разные языки компилируются разными компиляторами в.classФайлы в конечном итоге работают поверх виртуальной машины Java..classМожно использовать двоичный формат файла.WinHexПроверять.

java虚拟机

Можно сказать.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 поля:

字段的access_flags的取值

2.7 Коллекция таблиц методов

    u2             methods_count;//Class 文件的方法的数量
    method_info    methods[methods_count];//一个类可以有个多个方法

method_count представляет количество методов, а method_info представляет таблицу методов.

Описание методов в формате хранения Class file практически идентично описанию полей. Структура таблицы методов такая же, как у таблицы полей, включая, в свою очередь, флаги доступа, индексы имен, индексы дескрипторов и наборы таблиц атрибутов.

method_info (таблица методов) структура:

方法表的结构

Значение access_flag таблицы методов:

方法表的 access_flag 取值

Примечание: потому чтоvolatileмодификаторы иtransientМодификаторы не могут модифицировать методы, поэтому флаги доступа таблицы методов не имеют этих двух соответствующих флагов, а добавляютsynchronized,native,abstractи другие методы модификации ключевых слов, поэтому существует больше признаков, соответствующих этим ключевым словам.

2.8 Коллекция листа свойств

   u2             attributes_count;//此类的属性表中的属性数
   attribute_info attributes[attributes_count];//属性表集合

Файлы классов, таблицы полей и таблицы методов могут содержать собственный набор таблиц атрибутов для описания информации, специфичной для определенных сценариев. В отличие от порядка, длины и содержимого, требуемых для других элементов данных в файле Class, ограничения на коллекцию таблиц атрибутов немного слабее, и каждая таблица атрибутов больше не должна иметь строгого порядка, и до тех пор, пока она не продублировать существующее имя атрибута, любой Реализованный компилятор может записывать информацию о своих собственных атрибутах в таблицу атрибутов, а виртуальная машина Java будет игнорировать атрибуты, которые она не распознает при запуске.

Ссылаться на

Рекомендация проекта с открытым исходным кодом

Другие рекомендации автора по проектам с открытым исходным кодом:

  1. JavaGuide: [Изучение Java + руководство для интервью] Обложка, содержащая основные знания, которые необходимо освоить большинству Java-программистов.
  2. springboot-guide: Учебное пособие по Spring Boot, подходящее для начинающих и опытных разработчиков (поддержка в свободное время, добро пожаловать в совместную поддержку).
  3. programmer-advancement: Я думаю, некоторые хорошие привычки, которые должны быть у техников!
  4. spring-security-jwt-guide:Начинать с нуля! Spring Security с JWT (включая проверку авторизации) бэкэнд-часть кода.

публика