Heim  >  Artikel  >  Java  >  Einführung in die Klassendateistruktur der Java Virtual Machine

Einführung in die Klassendateistruktur der Java Virtual Machine

零下一度
零下一度Original
2017-06-25 10:41:041454Durchsuche

1. Vorwort

Freunde, die Java lernen, sollten alle wissen, dass Java von Anfang an das Banner der Plattformunabhängigkeit verwendet und sagt: „Einmal schreiben, überall ausführen“. Unabhängigkeit, Java Die Plattform hat auch eine andere Bedeutung: Um Sprachunabhängigkeit zu erreichen, ist die Dateistruktur oder der Bytecode der Klasse im Java-System von Anfang an sehr wichtig Spezifikationen, ist die Java-Sprachspezifikation und die andere ist die Java Virtual Machine-Spezifikation Die Java-Sprachspezifikation legt nur die Einschränkungen und Regeln fest, die sich auf die Java-Sprache beziehen, während dies bei der Virtual Machine-Spezifikation der Fall ist der echte grenzüberschreitende Entwurf aus Plattformperspektive .

Vielleicht denken die meisten Programmierer, dass es für die Java Virtual Machine selbstverständlich und natürlich ist, Java-Programme auszuführen, aber heute haben kommerzielle Organisationen und Open-Source-Organisationen zusätzlich zur Java-Sprache eine große Anzahl von Java-Programmen entwickelt. Sprachen, die auf virtuellen Maschinen laufen, wie Clojure, Groovy, JRuby, Jython, Scale usw. Sie können einen Java-Compiler verwenden, um Java-Code in eine Klassendatei zu kompilieren, die Bytecode speichert. Sie können auch einen Compiler in anderen Sprachen wie JRuby verwenden, um Programmcode in eine Klassendatei zu kompilieren weil die Java Virtual Machine denselben plattformunabhängigen Bytecode laden und ausführen kann. Mit anderen Worten, die Grundlage für die Unabhängigkeit der Sprachplattform ist das Speicherformat der virtuellen Maschine und des Bytecodes. Der virtuellen Maschine ist es egal, aus welcher Sprache die Klasse stammt, solange sie der Struktur der Klassendatei entspricht die Java Virtual Machine.

2. Kodierung und Zusammensetzung der Klassendatei

1) Die Klassendatei besteht aus einem Byte-Stream (8 Bit) , Diese Byteströme sind in strikter Übereinstimmung mit der vorgeschriebenen Reihenfolge angeordnet und es gibt keine Lücken zwischen den Bytes. Daten, die 8 Bytes überschreiten, werden in der Big-Endian-Reihenfolge gespeichert, d. h. in den höherwertigen Bytes werden an niedrigen Adressen gespeichert, und die niederwertigen Bytes werden an hohen Adressen gespeichert. Dies ist tatsächlich auch der Schlüssel zu plattformübergreifenden Klassendateien , da die PowerPC-Architektur die Big-Endian-Speicherreihenfolge verwendet. Während Prozessoren der x86-Serie die Little-Endian-Speicherreihenfolge verwenden, müssen Klassendateien daher unter verschiedenen Prozessorarchitekturen eine einheitliche Speicherreihenfolge beibehalten.

2) Die Klassendateistruktur verwendet eine C-ähnliche Struktur zum Speichern von Daten. Es gibt zwei Haupttypen von Datenelementen: vorzeichenlose Zahlen und Tabellen. Vorzeichenlose Zahlen werden zum Ausdrücken von Zahlen, Indexreferenzen und Zeichenfolgen verwendet usw. Beispielsweise stellen u1, u2, u4, u8 jeweils 1 Byte, 2 Bytes, 4 Bytes und 8 Bytes vorzeichenloser Zahlen dar, und die -Tabelle besteht aus mehreren zusammengesetzten Strukturen von vorzeichenlosen Zahlen und anderen Tabellen . Vielleicht ist sich hier nicht jeder ganz im Klaren darüber, was die vorzeichenlosen Zahlen und Tabellen oben sind, aber das spielt keine Rolle, ich werde es anhand von Beispielen erklären, wenn ich auf die Beispiele unten warte.
Nachdem wir die beiden oben genannten Punkte geklärt haben, werfen wir einen Blick auf die spezifischen Daten, die im Bytestrom enthalten sind und in strenger Reihenfolge in der Klassendatei angeordnet sind:

ClassFile {
    u4             magic;
    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];
}

Beim Betrachten des Bildes oben müssen wir auf eines achten. Beispielsweise stellt cp_info den Konstantenpool dar. Im Bild oben wird Constant_pool[constant_pool_count-1] verwendet, um den Konstantenpool darzustellen Constant_pool_count-1-Konstanten. Es wird hier ein Array-Ausdruck verwendet, aber denken Sie nicht fälschlicherweise, dass die konstanten Längen aller Konstantenpools gleich sind Tatsächlich werden hier Arrays nur zur Vereinfachung der Beschreibung verwendet. Aber hier ist es nicht wie bei einer Programmiersprache. Ein Array vom Typ int hat die gleiche Länge.

3. Detaillierte Einführung in jeden Teil der Klassendateistruktur

1) u4 magic stellt die magische Zahl dar und die magische Zahl belegt 4 Bytes. Es bedeutet tatsächlich, dass es sich bei dem Dateityp um eine Klassendatei und nicht um ein JPG-Bild oder einen AVI-Film handelt. Die magische Zahl, die der Klassendatei entspricht, ist 0xCAFEBABE.
2) u2-Minor_version stellt die Nebenversionsnummer der Klassendatei dar, und diese Versionsnummer ist eine vorzeichenlose Zahlendarstellung des Typs u2.
3) u2-Hauptversion stellt die Hauptversionsnummer der Klassendatei dar, und die Hauptversionsnummer ist eine vorzeichenlose Zahlendarstellung des Typs u2. Hauptversion und Nebenversion werden hauptsächlich verwendet, um anzuzeigen, ob die aktuelle virtuelle Maschine die aktuelle Version der Klassendatei akzeptiert . Die Versionen von Klassendateien, die von verschiedenen Versionen von Java-Compilern kompiliert werden, sind unterschiedlich. Virtuelle Maschinen höherer Versionen unterstützen die Klassendateistruktur, die von Compilern niedrigerer Versionen kompiliert wurde. Beispielsweise unterstützt die virtuelle Maschine, die Java SE 6.0 entspricht, die vom Compiler von Java SE 5.0 kompilierte Klassendateistruktur und umgekehrt .
4) u2 konstanter_pool_count repräsentiert die Anzahl der konstanten Pools. Hier müssen wir uns auf den Konstantenpool konzentrieren. Bitte verwechseln Sie ihn nicht mit dem Laufzeitkonstantenpool im JVM-Speichermodell. Der Konstantenpool in der Klassendatei speichert hauptsächlich Literale und Symbolreferenzen Dazu gehören hauptsächlich Zeichenfolgen, der Wert einer Endkonstante oder der Anfangswert einer Eigenschaft usw., während symbolische Referenzen hier hauptsächlich die vollständig qualifizierten Namen von Klassen und Schnittstellen, die Namen und Deskriptoren von Feldern sowie die Namen und Deskriptoren von Methoden speichern Der Name ist möglicherweise für jeden leicht zu verstehen. Was das Konzept der Deskriptoren betrifft, werden wir im Folgenden auf die Feldtabelle und die Methodentabelle eingehen. Darüber hinaus weiß jeder, dass das Speichermodell von JVM aus Heap, Stapel, Methodenbereich und Programmzähler besteht und es im Methodenbereich einen Bereich gibt, der als Laufzeitkonstantenpool bezeichnet wird. Die im Laufzeitkonstantenpool gespeicherten Dinge Tatsächlich werden verschiedene Literale und Symbolreferenzen vom Prozessor generiert, aber der Laufzeitkonstantenpool ist dynamisch. Er kann zur Laufzeit andere Konstanten hinzufügen >. 5) cp_info stellt den Konstantenpool dar, der die verschiedenen oben genannten Literale und Symbolreferenzen enthält. Die im Konstantenpool platzierten Datenelemente enthalten insgesamt 14 Konstanten. Jede Konstante ist eine Tabelle, und jede Konstante verwendet ein gemeinsames Teil-Tag, um anzugeben, um welche Art von Konstante es sich handelt.

Konstantentyp Wert
CONSTANT_Class td> 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 td> 1
CONSTANT_MethodHandle 15
CONSTANT_MethodType 16
CONSTANT_InvokeDynamic 18


6)u2 access_flags 表示类或者接口的访问信息,具体如下图所示:

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

7)u2 this_class 表示类的常量池索引,指向常量池中CONSTANT_Class的常量
8)u2 super_class 表示超类的索引,指向常量池中CONSTANT_Class的常量
9)u2 interface_counts 表示接口的数量
10)u2 interface[interface_counts]表示接口表,它里面每一项都指向常量池中CONSTANT_Class常量
11)u2 fields_count 表示类的实例变量和类变量的数量
12) field_info fields[fields_count]表示字段表的信息,其中字段表的结构如下图所示:

field_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

上图中access_flags表示字段的访问表示,比如字段是public、private、protect 等,name_index表示字段名称,指向常量池中类型是CONSTANT_UTF8的常量,descriptor_index表示字段的描述符,它也指向常量池中类型为 CONSTANT_UTF8的常量,attributes_count表示字段表中的属性表的数量,而属性表是则是一种用与描述字段,方法以及 类的属性的可扩展的结构,不同版本的Java虚拟机所支持的属性表的数量是不同的。
13) u2 methods_count表示方法表的数量
14)method_info 表示方法表,方法表的具体结构如下图所示:

method_info {
    u2             access_flags;
    u2             name_index;,
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

其中access_flags表示方法的访问表示,name_index表示名称的索引,descriptor_index表示方法的描述符,attributes_count以及attribute_info类似字段表中的属性表,只不过字段表和方法表中属性表中的属性是不同的,比如方法表中就有Code属性,表示方法的代码,而字段表中就没有Code属性。
15) attribute_count表示属性表的数量,说到属性表,我们需要明确以下几点:
属性表存在于Class文件结构的最后,字段表,方法表以及Code属性中,也就是说属性表中也可以存在属性表,属性表的长度是不固定的,不同的属性,属性表的长度是不同的

Das obige ist der detaillierte Inhalt vonEinführung in die Klassendateistruktur der Java Virtual Machine. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn