Les amis qui étudient Java devraient tous savoir que Java utilise depuis le début la bannière de l'indépendance de la plate-forme, en disant "écrire une fois, exécuter n'importe où". En fait, en ce qui concerne la non-pertinence, la plate-forme Java a une autre non-pertinence, qui est l'indépendance du langage. , pour obtenir l'indépendance du langage, puis la structure de fichiers de la classe dans le système Java ou Il est très important de dire qu'il s'agit de bytecode. En fait, Java a eu deux ensembles de spécifications depuis le début, 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 ne fait que stipuler les contraintes. liés au langage et aux règles Java, et les spécifications des machines virtuelles sont véritablement conçues dans une perspective multiplateforme. Aujourd'hui, nous allons prendre un exemple pratique pour voir à quoi devrait ressembler le bytecode correspondant à un fichier Class en Java. Cet article expliquera d'abord en général le contenu de la classe, puis utilisera une classe Java réelle pour analyser la structure des fichiers de la classe.
Avant de continuer, nous devons d’abord clarifier les points suivants :
1) Les fichiers de classe sont composés de flux d'octets de 8 octets. Ces flux d'octets sont strictement disposés dans l'ordre spécifié et il n'y a aucun espace entre les octets. Pour les fichiers dépassant 8 octets, les données seront stockées dans l'ordre Big-Endian. c'est-à-dire que l'octet de poids fort est stocké à l'adresse basse et l'octet de poids faible est stocké à l'adresse haute. C'est également 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, afin que les fichiers de classe soient conservés sous chaque architecture de processeur. Stockage unifié Dans cet ordre, les spécifications des machines virtuelles doivent être unifiées.
2) La structure du fichier de classe 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, telles que u1, u2. , u4 et u8 représentent respectivement 1 octet, 2 octets, 4 octets et 8 octets de nombres non signés, et la table est une structure composite composée de plusieurs nombres non signés et d'autres tables. Peut-être que tout le monde ici ne sait pas très bien ce que sont les nombres et les tableaux non signés, mais cela n'a pas d'importance, je l'expliquerai avec des exemples lorsque je donnerai 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ées dans un ordre strict dans le fichier Class :
Lorsque vous regardez l'image ci-dessus, il y a une chose à laquelle nous devons prêter attention, comme cp_info, cp_info représente le pool constant. Dans l'image ci-dessus, constant_pool[constant_pool_count-1] est utilisé pour représenter le pool constant avec constant_pool_co. unt-1 constante, elle est exprimée ici sous la forme d'un tableau, mais ne pensez pas à tort que les longueurs constantes de tous les pools constants sont les mêmes. En fait, cet endroit utilise la méthode du tableau juste pour faciliter la description, mais. ce n'est pas comme ça. Dans les langages de programmation, un tableau de type int a la même longueur que chaque int. Après avoir clarifié ce point, regardons en arrière et voyons ce que représente spécifiquement chaque élément de l'image ci-dessus.
1) u4 magic représente le nombre magique, et le nombre magique occupe 4 octets. Que fait le nombre magique ? 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. Une version supérieure de la machine virtuelle prend en charge la structure de fichiers Class compilée par une version inférieure du compilateur. Par exemple, la machine virtuelle correspondant à Java SE 6.0 prend en charge la structure de fichiers Class compilée par le compilateur Java SE 5.0, mais pas l'inverse.
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 des littéraux et des références de symboles, où les littéraux incluent principalement des chaînes. valeur de la constante finale ou Ou la valeur initiale d'un certain attribut, etc., tandis que les références de symboles stockent principalement les noms complets des classes et des interfaces, les noms de champs et de descripteurs, les noms de méthodes et de descripteurs. Les noms ici peuvent être faciles à comprendre pour tout le monde, comme pour le. notion de descripteurs, nous en reparlerons plus tard lorsque nous discuterons 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 de 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 les éléments stockés dans le pool de constantes d'exécution. immortalité du compilateur. Divers littéraux et références de symboles, 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 éléments de données placés dans le pool de constantes dans la spécification de machine virtuelle Java Java SE 7 Edition. Chaque constante est une table et chaque constante utilise une balise partielle commune pour indiquer de quel type il s'agit.
Les détails spécifiques sont brièvement décrits ci-dessous et nous les affinerons dans des exemples ultérieurs.
L'indicateur de balise CONSTANT_Utf8_info est 1, l'indicateur de balise CONSTANT_Integer_info de chaîne codée UTF-8 est 3, l'indicateur de balise littéral entier CONSTANT_Float_info est 4, le drapeau de balise littéral à virgule flottante CONSTANT_Long_info est 5, le drapeau de balise entier long littéral CONSTANT_Double_info Le bit est 6, l'indicateur de balise CONSTANT_Class_info littéral double précision est 7, La référence symbolique de la balise CONSTANT_String_info de la classe ou de l'interface est 8, la balise littérale CONSTANT_Fieldref_info du type chaîne est 9, la référence symbolique du champ CONSTANT_Methodref_info balise est 10, la référence symbolique de la méthode dans la classe CONSTANT_InterfaceMethodref_info est 11, Symbolique référence à la méthode dans la balise CONSTANT_NameAndType_info de l'interface Bit d'indicateur 12, noms de champs et de méthodes et références symboliques aux types
6) u2 access_flags représente les informations d'accès de la classe ou de l'interface, comme le montre la figure suivante :
7) u2 this_class représente l'index de pool constant de la classe, pointant vers la constante de CONSTANT_Class_info dans le pool constant
8) u2 super_class représente l'index de la super classe, pointant vers la constante de CONSTANT_Class_info dans le pool de constantes
9) u2 interface_counts représente le nombre d'interfaces
10) u2 interface[interface_counts] représente la table d'interface, chaque élément qu'elle contient pointe vers la constante CONSTANT_Class_info dans le pool de constantes
11) u2 field_count représente le nombre de variables d'instance et de variables de classe de la classe
12) field_info lists[fields_count] représente les informations de la table de champs, où la structure de la table de champs est la suivante :
Dans la figure ci-dessus, access_flags représente la représentation d'accès du champ. Par exemple, le champ est public, privé et protégé. etc., name_index représente le nom du champ, pointant vers la constante de type CONSTANT_UTF8_info dans le pool de constantes, descriptor_index représente le descripteur du champ, qui pointe également vers la constante de type CONSTANT_UTF8_info dans le pool de constantes, attributs_count représente le nombre de tables attributaires dans la table des champs et la table attributaire. Il s'agit d'une structure extensible utilisée pour décrire les champs, les méthodes et les attributs de classe. Différentes versions de la machine virtuelle Java prennent en charge différents nombres de tables attributaires.
13) u2 METHODS_count représente le nombre de tables de méthodes
14) method_info représente la table des méthodes. La structure spécifique de la table des méthodes est la suivante :
Parmi eux, access_flags représente la représentation d'accès de la méthode, name_index représente l'index du nom, descriptor_index représente le descripteur de la méthode,attributs_count etattribut_info sont similaires aux tables d'attributs de la table de champs, sauf que les attributs de la table d'attributs dans la table des champs et la table des méthodes sont différents, par exemple L'attribut Code dans la table des méthodes représente le code de la méthode, mais il n'y a pas d'attribut Code dans la table des champs. Le nombre d'attributs présents dans la classe spécifique sera discuté plus tard lorsque nous examinerons la table attributaire dans la structure du fichier de classe.
15)attribut_count représente le nombre de tables attributaires. En ce qui concerne les tables attributaires, nous devons clarifier les points suivants :
La table attributaire existe à la fin de la structure du fichier Classe, dans la table des champs, la table des méthodes et l'attribut Code. C'est-à-dire que la table attributaire peut également exister dans la table attributaire. La longueur de la table attributaire n'est pas fixe. Différents attributs ont des longueurs différentes.
Après avoir décrit la composition de chaque élément dans la structure du fichier de classe ci-dessus, nous utilisons un exemple pratique pour expliquer le contenu suivant.
Copiez le code comme suit :
paquet com.ejushang.TestClass ;
la classe publique TestClass implémente Super{
private static final int staticVar = 0;
private int instanceVar = 0 ;
public int instanceMethod(int param){
retourner paramètre+1 ;
}
}
interface Super{ }
La structure binaire de TestClass.class correspondant à TestClass.java compilé via javac de jdk1.6.0_37 est illustrée dans la figure ci-dessous :
Ensuite, nous analyserons le flux d'octets dans la figure ci-dessus en fonction de la structure de fichier de Class mentionnée précédemment.
1) Nombre magique <br/>D'après la structure des fichiers de Class, nous savons que les 4 premiers octets sont le nombre magique. Dans l'image ci-dessus, le contenu de l'adresse 00000000h-00000003h est le nombre magique. nous pouvons connaître le numéro magique du fichier Class. Le numéro est 0xCAFEBABE.
2) Numéros de version majeure et mineure <br/>Les 4 octets suivants sont les numéros de version majeure et mineure. À partir de la figure ci-dessus, nous pouvons voir que les numéros correspondants de 00000004h à 00000005h sont 0 × 0000, donc la version mineure de la classe. est 0×0000, et le contenu correspondant de 00000006h-00000007h est 0×0032, donc la version major_version du fichier Class est 0×0032, qui est exactement la version majeure et mineure correspondant à la classe compilée par jdk1.6.0 sans le paramètre cible.
3) Le nombre de pools constants <br/>Les 2 octets suivants représentent le nombre de pools constants de 00000008h à 00000009h. À partir de la figure ci-dessus, nous pouvons savoir que sa valeur est 0×0018, soit 24 en décimal, mais pour. Le nombre de pools constants doit être clarifié. Le nombre de pools constants est constant_pool_count-1. La raison pour laquelle il est réduit de un est que l'index 0 signifie que les éléments de données de la classe ne font référence à aucune constante dans le pool constant.
4) Pool de constantes <br/>Nous avons dit plus haut qu'il existe différents types de constantes dans le pool de constantes. Jetons un coup d'œil à la première constante de TestClass.class. Nous savons que chaque constante est représentée par un identifiant de balise de type u1. Le type de constante, à 0000000ah dans l'image ci-dessus Le contenu est 0x0A, qui converti en système secondaire est 10. D'après la description ci-dessus du type de constante, on peut voir que la constante avec la balise 10 est Constant_Methodref_info, et la structure de Constant_Methodref_info est comme indiqué dans la figure ci-dessous :
Parmi eux, class_index pointe vers la constante de type CONSTANT_Class_info dans le pool de constantes. Il ressort de la structure du fichier binaire de TestClass que la valeur de class_index est 0×0004 (l'adresse est 0000000bh-0000000ch), ce qui signifie qu'elle pointe vers la quatrième constante.
name_and_type_index pointe vers la constante de type CONSTANT_NameAndType_info dans le pool de constantes. Comme le montre la figure ci-dessus, la valeur de name_and_type_index est 0×0013, ce qui signifie qu'elle pointe vers la 19e constante du pool de constantes.
Ensuite, vous pouvez utiliser la même méthode pour rechercher toutes les constantes du pool de constantes. Cependant, JDK fournit un outil pratique qui nous permet de visualiser les constantes contenues dans le pool de constantes. Vous pouvez obtenir toutes les constantes du pool de constantes via javap -verbose TestClass. La capture d'écran est la suivante :
D'après l'image ci-dessus, nous pouvons clairement voir qu'il y a 24 constantes dans le pool de constantes de TestClass. N'oubliez pas la 0ème constante, car la 0ème constante est utilisée pour indiquer que les éléments de données de Class ne font référence à aucune constante dans le. piscine constante. D'après l'analyse ci-dessus, nous savons que la première méthode de représentation constante de TestClass est que la quatrième constante pointée par class_index est java/lang/Object et que la 19e valeur constante pointée par name_and_type_index est <init>:()V From It can. On voit ici que la première constante représentant une méthode représente la méthode constructeur d'instance générée par le compilateur Java. D'autres constantes du pool de constantes peuvent être analysées de la même manière. OK, après avoir analysé le pool constant, analysons ensuite access_flags.
5) u2 access_flags représente les informations d'accès sur les classes ou les interfaces. Par exemple, Class indique s'il s'agit d'une classe ou d'une interface, si elle est publique, statique, finale, etc. La signification de l'indicateur d'accès spécifique a déjà été mentionnée. Jetons un coup d'œil à l'indicateur d'accès de TestClass. L'indicateur d'accès de la classe est de 0000010dh-0000010e et la valeur est 0 × 0021. Selon les bits d'indicateur des différents indicateurs d'accès mentionnés précédemment, nous pouvons savoir : 0 × 0021 = 0 × 0001 | 0 × 0020, c'est-à-dire que ACC_PUBLIC et ACC_SUPER sont True, ACC_PUBLIC est facile à comprendre et ACC_SUPER est un indicateur qui sera porté par les classes compilées après jdk1.2.
6) u2 this_class représente la valeur d'index de la classe, qui est utilisée pour représenter le nom complet de la classe. La valeur d'index de la classe est comme indiqué dans la figure ci-dessous :
Comme le montre clairement la figure ci-dessus, la valeur de l'indice de classe est 0×0003, ce qui correspond à la troisième constante du pool de constantes, grâce au résultat javap, nous savons que la troisième constante est une constante de type CONSTANT_Class_info, via. dont nous pouvons connaître tous les détails de la classe. Le nom qualifié est : com/ejushang/TestClass /TestClass.
7) u2 super_class représente la valeur d'index de la classe parent de la classe actuelle. La valeur d'index pointe vers une constante de type CONSTANT_Class_info dans le pool de constantes. La valeur d'index de la classe parent est comme indiqué dans la figure ci-dessous. 0 × 0004. Vérifiez les quatre premières constantes du pool de constantes, vous pouvez voir que le nom complet de la classe parent de TestClass est : java/lang/Object.
8) interfaces_count et interfaces[interfaces_count] représentent le nombre d'interfaces et chaque interface spécifique. Le nombre d'interfaces et d'interfaces de TestClass est comme indiqué dans la figure ci-dessous, où 0×0001 signifie que le nombre d'interfaces est 1 et 0×. 0005 signifie l'index de l'interface dans la valeur du pool constant, recherchez la cinquième constante dans le pool constant, son type est CONSTANT_Class_info et sa valeur est : com/ejushang/TestClass/Super
9) field_count et field_info , field_info représente le nombre de tables field_info dans la classe et field_info représente les variables d'instance et les variables de classe de la classe. Il convient de noter ici que field_info n'inclut pas les champs hérités de la classe parent. field_info est comme indiqué dans la figure ci-dessous :
Parmi eux, access_flags représente l'indicateur d'accès du champ, tel que public, privé, protégé, statique, final, etc. La valeur de access_flags est comme indiqué dans la figure ci-dessous :
Parmi eux, name_index et descriptor_index sont tous deux des valeurs d'index du pool de constantes, qui représentent respectivement le nom du champ et le descripteur du champ. Le nom du champ est facile à comprendre, mais comment comprendre le descripteur du champ. champ? En fait, dans la spécification JVM, les descripteurs de champs sont spécifiés comme le montre la figure suivante :
Parmi eux, tout le monde doit faire attention à la dernière ligne de l'image ci-dessus. Elle représente le descripteur d'un tableau unidimensionnel. Le descripteur de String[][] sera [[ Ljava/lang/String, et la description de String[][] sera [[ Ljava/lang/String]. int[][] Le symbole est [[I. Les attributs_count et attributs_info suivants représentent respectivement le nombre de tables attributaires et de tables attributaires. Prenons l'exemple de TestClass ci-dessus et jetons un œil à la table de champs de TestClass.
Tout d'abord, jetons un coup d'œil au nombre de champs. Le nombre de champs dans TestClass est comme indiqué dans la figure ci-dessous :
Comme le montre l'image ci-dessus, TestClass a deux champs. En regardant le code source de TestClass, nous pouvons voir qu'il n'y a en effet que deux champs. Ensuite, regardons le premier champ. Nous savons que le premier champ devrait être. private int staticVar, dont la représentation binaire dans le fichier de classe est la suivante :
Parmi eux, 0x001A représente l'indicateur d'accès. En regardant la table access_flags, nous pouvons savoir qu'il s'agit de ACC_PRIVATE, ACC_STATIC, ACC_FINAL. Ensuite, 0×0006 et 0×0007 représentent respectivement les 6ème et 7ème constantes du pool de constantes. en regardant le pool de constantes, nous pouvons savoir que leurs valeurs sont : staticVar et I, où staticVar est le nom du champ et I est le descripteur du champ. Grâce à l'explication ci-dessus des descripteurs, ce que je décris est une variable de type int. Ensuite, 0 × 0001 représente le nombre de tables attributaires dans la table de champs staticVar. À partir de la figure ci-dessus, on peut voir qu'il y a 1 table attributaire correspondante. au champ staticVar. 0×0008 représente la 8ème constante du pool de constantes, vous pouvez voir que cet attribut est l'attribut ConstantValue et que le format de l'attribut ConstantValue est comme indiqué dans la figure ci-dessous :
Parmi eux,attribut_name_index exprime l'index du pool constant du nom de l'attribut. Dans cet exemple, il s'agit de ConstantValue. L'attribut_length de ConstantValue a une longueur fixe de 2 et constantValue_index représente la référence dans le pool constant. ×0009. Vous pouvez visualiser la 9ème constante. Vous savez, elle représente une constante de type CONSTANT_Integer_info dont la valeur est 0.
Cela dit, private static final int staticVar=0, parlons de private int instanceVar=0 de TestClass. Dans cet exemple, la représentation binaire de instanceVar est la suivante :
Parmi eux, 0 × 0002 signifie que la marque d'accès est ACC_PRIVATE, 0x000A signifie le nom du champ, qui pointe vers la 10ème constante du pool de constantes. En regardant le pool de constantes, vous pouvez savoir que le nom du champ est instanceVar et. 0× 0007 représente le descripteur du champ, qui pointe vers la 7ème constante du pool de constantes, vous pouvez savoir que la 7ème constante est I, qui représente le type d'instanceVar. Enfin, 0×0000 représente le. le nombre de tables attributaires est 0. .
10) METHODS_count et METHODS_INFO , où METHODS_count représente le nombre de méthodes, et METHODS_INFO représente la table des méthodes, où la structure de la table des méthodes est comme indiqué dans la figure ci-dessous :
Comme le montre la figure ci-dessus, les structures de method_info et field_info sont très similaires. Tous les bits d'indicateur et valeurs de access_flag dans la table des méthodes sont comme indiqué dans la figure ci-dessous :
Parmi eux, name_index et descriptor_index représentent le nom et le descripteur de la méthode, et ce sont des index pointant respectivement vers le pool de constantes. Ici, nous devons expliquer le descripteur de méthode. La structure du descripteur de méthode est : (liste de paramètres) valeur de retour Par exemple, le descripteur de public int instanceMethod(int param) est : (I) I, ce qui signifie qu'il a un int. paramètre de type.Et la valeur de retour est également une méthode de type int.Vient ensuite le nombre d'attributs et la table attributaire. Bien que la table des méthodes et la table des champs aient toutes deux le nombre d'attributs et la table attributaire, les attributs qu'elles contiennent sont. différent. Examinons ensuite la représentation binaire de la table de méthodes à l'aide de TestClass. Tout d’abord, jetons un œil au nombre de tables de méthodes. La capture d’écran est la suivante :
Comme le montre la figure ci-dessus, le nombre de tables de méthodes est de 0 × 0002, ce qui signifie qu'il existe deux méthodes. Ensuite, analysons la première méthode. Examinons d'abord access_flag, name_index, descriptor_index de la première méthode de TestClass. . La capture d'écran est la suivante :
À partir de la figure ci-dessus, nous pouvons savoir que access_flags est 0 × 0001. D'après la description ci-dessus de l'indicateur access_flags, nous pouvons voir que la valeur de access_flags de la méthode est ACC_PUBLIC et que le name_index est 0x000B. La 11ème constante, sachant que le nom de la méthode est <init>, 0x000C signifie descriptor_index signifie la 12ème constante dans le pool de constantes, et sa valeur est ()V, ce qui signifie que la méthode <init> n'a ni paramètres ni valeur de retour. En fait, il s'agit des méthodes de constructeur d'instance générées automatiquement par le compilateur. Le 0 × 0001 suivant indique que la table de méthode de la méthode <init> a 1 attribut. La capture d'écran de l'attribut est la suivante :
Comme le montre la figure ci-dessus, la constante dans le pool de constantes correspondant à 0x000D est Code, qui représente l'attribut Code de la méthode. Donc ici, tout le monde doit comprendre que les codes de la méthode sont stockés dans l'attribut Code de l'attribut. table dans la table des méthodes du fichier Class. Ensuite, nous analysons l'attribut Code. La structure de l'attribut Code est présentée dans la figure ci-dessous :
Parmi eux,attribut_name_index pointe vers la constante dont la valeur est Code dans le pool de constantes, et la longueur deattribut_length indique la longueur de la table attributaire Code (il convient de noter que la longueur n'inclut pas la longueur de 6 octets deattribut_name_index etattribut_length ).
max_stack représente la profondeur maximale de la pile. La machine virtuelle alloue la profondeur des opérandes dans le cadre de pile en fonction de cette valeur au moment de l'exécution, et max_locals représente l'espace de stockage de la table de variables locales.
L'unité de max_locals est l'emplacement, qui est la plus petite unité permettant à la machine virtuelle d'allouer de la mémoire aux variables locales au moment de l'exécution, les types de données qui ne dépassent pas les types de 32 bits, tels que byte, char, int, etc., occupent 1. fente, tandis que double et Long Un type de données 64 bits doit allouer 2 emplacements. De plus, la valeur de max_locals n'est pas la somme de la mémoire requise par toutes les variables locales, car les emplacements peuvent être réutilisés lorsque la variable locale dépasse sa portée. l’emplacement occupé sera réutilisé.
code_length représente le nombre d'instructions de bytecode et code représente les instructions de bytecode. À partir de la figure ci-dessus, nous pouvons savoir que le type de code est u1. La valeur d'un type u1 est 0×00-0xFF et la décimale correspondante est 0-. 255. Actuellement, la spécification de la machine virtuelle a défini plus de 200 instructions.
exception_table_length et exception_table représentent respectivement les informations d'exception correspondant à la méthode.
attribuer_compte et attribut_info représentent respectivement le nombre d'attributs et la table attributaire dans l'attribut Code. On peut voir à partir d'ici que la table attributaire est très flexible dans la structure de fichier de la classe. Elle peut exister dans le fichier Classe, la table des méthodes, le champ. table et attribut Code.
Ensuite, nous continuons à analyser l'exemple ci-dessus. À partir de la capture d'écran de l'attribut Code de la méthode init ci-dessus, nous pouvons voir que la longueur de la table attributaire est 0×00000026, la valeur de max_stack est 0×0002 et la valeur de max_locals est 0× 0001, la longueur de code_length est 0x0000000A, puis 00000149h- 00000152h est un bytecode. Ensuite, la longueur de exception_table_length est de 0×0000 et la valeur d'attribut_count est de 0×0001. La valeur de 00000157h-00000158h est 0x000E, qui représente le nom de l'attribut dans le pool de constantes. pour obtenir le 14ème. La valeur de la constante est LineNumberTable, LineNu. mberTable est utilisé pour décrire la correspondance entre le numéro de ligne du code source Java et le numéro de ligne du bytecode. Si vous annulez la génération de ces informations via le paramètre du compilateur -g:none, l'impact le plus important sera. be Lorsqu'une exception se produit, le numéro de ligne d'erreur ne peut pas être affiché sur la pile et les points d'arrêt ne peuvent pas être définis en fonction du code source lors du débogage. Examinons ensuite la structure de LineNumberTable, comme indiqué ci-dessous :
Parmi eux,attribut_name_index a été mentionné ci-dessus et représente l'index du pool de constantes,attribut_length représente la longueur de l'attribut et les tables start_pc et line_number représentent le numéro de ligne du bytecode et le numéro de ligne du code source. Le flux d'octets de la propriété LineNumberTable dans cet exemple est le suivant :
Après avoir analysé la première méthode de TestClass ci-dessus, nous pouvons analyser la deuxième méthode de TestClass de la même manière. La capture d'écran est la suivante :
Parmi eux, access_flags est 0×0001, name_index est 0x000F et descriptor_index est 0×0010 En regardant le pool de constantes, vous pouvez savoir que cette méthode est la méthode public int instanceMethod (int param). Grâce à une méthode similaire à celle ci-dessus, nous pouvons savoir que l'attribut Code de instanceMethod est tel qu'indiqué dans la figure ci-dessous :
Enfin, analysons les attributs du fichier Class. De 00000191h à 00000199h se trouve la table d'attributs dans le fichier Class, où 0×0011 représente le nom de l'attribut. En regardant le pool de constantes, nous pouvons savoir que le nom de l'attribut est SourceFile. .Jetons un coup d'œil à la structure de SourceFile comme suitComme le montre la figure :
Parmi eux,attribut_length est la longueur de l'attribut et sourcefile_index pointe vers la constante du pool de constantes dont la valeur est le nom du fichier de code source. Dans cet exemple, la capture d'écran de l'attribut SourceFile est la suivante :
Parmi eux, attributs_length est 0×00000002, ce qui signifie que la longueur est de 2 octets et la valeur de sourcefile_index est 0×0012. En regardant la 18e constante du pool de constantes, vous pouvez savoir que le nom du fichier de code source est TestClass. .Java
Enfin, j'espère que les amis intéressés par la technologie pourront communiquer davantage. Weibo personnel : (http://weibo.com/xmuzyq)