Maison >Java >javaDidacticiel >Introduction à la structure des fichiers de classe de la machine virtuelle Java

Introduction à la structure des fichiers de classe de la machine virtuelle Java

零下一度
零下一度original
2017-06-25 10:41:041536parcourir

1. Avant-propos

Les amis qui étudient Java devraient tous savoir que Java utilise la bannière de l'indépendance de la plate-forme depuis le début, en disant "écrivez une fois, exécutez n'importe où". , Java Il existe une autre non-pertinence de la plate-forme, qui est l'indépendance du langage. Pour obtenir l'indépendance du langage, la structure des fichiers ou le bytecode du système Java est très importante. En fait, Java en a deux types. ensembles de spécifications, l'une est la spécification du langage Java, et l'autre est la spécification de la machine virtuelle Java La spécification du langage Java stipule uniquement les contraintes et les règles liées au langage Java, tandis que la machine virtuelle. la spécification est la véritable spécification transversale Conçue du point de vue de la plateforme .

Peut-être que la plupart des programmeurs pensent qu'il est naturel et naturel que la machine virtuelle Java exécute des programmes Java, mais aujourd'hui, les organisations commerciales et les organisations open source ont développé un grand nombre de programmes Java en plus du langage Java. Langages exécutés sur des machines virtuelles, tels que Clojure, Groovy, JRuby, Jython, Scale, etc. Vous pouvez utiliser un compilateur Java pour compiler le code Java dans un fichier de classe qui stocke le bytecode. Vous pouvez également utiliser un compilateur dans d'autres langages tels que JRuby pour compiler le code du programme dans un fichier de classe. La raison pour laquelle Java peut s'exécuter sur toutes les plates-formes. car la machine virtuelle Java peut charger et exécuter le même bytecode indépendant de la plate-forme. En d'autres termes, la base pour parvenir à l'indépendance de la plate-forme linguistique est le format de stockage de la machine virtuelle et du bytecode. La machine virtuelle ne se soucie pas de la langue d'origine de la classe, tant qu'elle est conforme à la structure du fichier de classe, elle peut s'exécuter. la machine virtuelle Java.

2. Encodage et composition du fichier de classe

1) Le fichier de classe est composé d'un flux d'octets basé sur des octets (8 bits) , ces flux d'octets sont disposés en stricte conformité avec l'ordre prescrit, et il n'y a aucun espace entre les octets. Les données dépassant 8 octets seront stockées dans l'ordre Big-Endian, c'est-à-dire les octets de poids fort. sont stockés aux adresses basses, et les octets de poids faible sont stockés aux adresses hautes. En fait, c'est aussi la clé des fichiers de classe multiplateformes , car l'architecture PowerPC utilise l'ordre de stockage Big-Endian, tandis que les processeurs de la série x86 utilisent l'ordre de stockage Little-Endian. Par conséquent, pour que les fichiers de classe maintiennent un ordre de stockage unifié sous différentes architectures de processeur, les spécifications des machines virtuelles doivent les unifier.

2) La structure du fichier Class utilise une structure de type langage C pour stocker les données. Il existe deux principaux types d'éléments de données : les nombres non signés et les tableaux sont utilisés pour exprimer des nombres, des références d'index et des chaînes. , etc. , par exemple, u1, u2, u4, u8 représentent respectivement 1 octet, 2 octets, 4 octets et 8 octets de nombres non signés , et la table a plusieurs Une structure composite composée de nombres non signés et autres tableaux . Peut-être que tout le monde ici ne sait pas très bien quels sont les nombres et les tableaux non signés ci-dessus, mais cela n'a pas d'importance, je l'expliquerai avec des exemples en attendant les exemples ci-dessous.
Après avoir clarifié les deux points ci-dessus, examinons les données spécifiques contenues dans le flux d'octets disposés dans un ordre strict dans le fichier Class :

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];
}

En regardant l'image ci-dessus, il y a une chose à laquelle nous devons prêter attention. Par exemple, cp_info représente le pool constant. Dans l'image ci-dessus, constant_pool[constant_pool_count-1] est utilisé pour représenter que le pool constant a. constant_pool_count-1 constantes. Il utilise ici une expression de tableau, mais ne pensez pas à tort que les longueurs constantes de tous les pools constants sont les mêmes En fait, cet endroit utilise des tableaux juste pour faciliter la description, mais ici ce n'est pas comme un langage de programmation. Un tableau de type int, chaque int a la même longueur.

3. Introduction détaillée de chaque partie de la structure du fichier de classe

1) u4 magic représente le nombre magique, et le nombre magique occupe 4 octets. Cela signifie en fait que le type de fichier est un fichier de classe, et non une image JPG ou un film AVI. Le nombre magique correspondant au fichier Class est 0xCAFEBABE.
2) u2 minor_version représente le numéro de version mineure du fichier Class, et ce numéro de version est une représentation numérique non signée du type u2.
3) u2 major_version représente le numéro de version majeure du fichier Class, et le numéro de version majeure est une représentation numérique non signée du type u2. major_version et minor_version sont principalement utilisés pour indiquer si la machine virtuelle actuelle accepte la version actuelle du fichier Class . Les versions des fichiers Class compilés par les différentes versions des compilateurs Java sont différentes. Les machines virtuelles de version supérieure prennent en charge la structure de fichiers Class compilée par les compilateurs de version inférieure. Par exemple, la machine virtuelle correspondant à Java SE 6.0 supporte la structure de fichier Class compilée par le compilateur de Java SE 5.0, et vice versa .
4) u2 constant_pool_count représente le nombre de pools constants. Ici, nous devons nous concentrer sur ce qu'est le pool de constantes. Veuillez ne pas le confondre avec le pool de constantes d'exécution dans le modèle de mémoire Jvm Le pool de constantes dans le fichier Class stocke principalement les littéraux et les références de symboles, où les littéraux. incluent principalement des chaînes, la valeur d'une constante finale ou la valeur initiale d'une propriété, etc., tandis que les références symboliques stockent principalement les noms complets de classes et d'interfaces, les noms et descripteurs de champs, les noms et descripteurs de méthodes, ici le nom Il peut être facile à comprendre pour tout le monde. Quant au concept de descripteurs, nous parlerons ci-dessous de la table des champs et de la table des méthodes. De plus, tout le monde sait que le modèle de mémoire Jvm se compose d'un tas, d'une pile, d'une zone de méthode et d'un compteur de programme, et qu'il existe une zone dans la zone de méthode appelée pool de constantes d'exécution Les éléments stockés dans le pool de constantes d'exécution sont. en fait compilé Divers littéraux et références de symboles générés par le processeur, mais le pool de constantes d'exécution est dynamique Il peut y ajouter d'autres constantes au moment de l'exécution. La plus représentative est la méthode interne de String. . 5) cp_info représente le pool de constantes, qui contient les différents littéraux et références de symboles mentionnés ci-dessus. Il y a un total de 14 constantes dans les éléments de données placés dans le pool de constantes. Chaque constante est un tableau et chaque constante utilise une balise partielle commune pour indiquer de quel type de constante il s'agit.

Type constant Valeur
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
Constant Type Value
CONSTANT_Class 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 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属性中,也就是说属性表中也可以存在属性表,属性表的长度是不固定的,不同的属性,属性表的长度是不同的

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn