当前位置:网站首页>Un article traite de la microstructure et des instructions de la classe
Un article traite de la microstructure et des instructions de la classe
2022-07-05 22:48:00 【Des milliers de kilomètres de long et de large】
Table des matières
1.1. Class Structure du fichier Bytecode
1.2. Class Type de données du fichier
1.4. Numéro de version du document
1.5. Collection de pools constants
1.5.1. Compteur de pool constant
1.5.2. Tableau des pools constants
1.7. Index des classes、Index parent、Index des interfaces
1.7.1. this_class(Index des classes)
1.7.2. super_class(Index parent)
1.8. Collection de tables de champs
1.9. Collection de tables de méthodes
1.10. Collection de feuilles de propriétés
Sections précédentes , Nous nous présentons tous d'un point de vue macro JVM Le rôle et la fonction des différentes parties de , Ce chapitre commence par un point de vue microscopique , Analyse spécifique à l'angle Bytecode JVMComment ça s'est passé. Le contenu de ce chapitre est l'approfondissement et l'extension des chapitres précédents , Il contient en particulier les parties importantes suivantes :
1.class Qu'est - ce qu'il y a dans le fichier Bytecode ,Comment ça s'est passé.
2. Comment ces bytecodes sont exécutés étape par étape , C'est - à - dire comment les instructions d'exécution fonctionnent .
3. Nous analysons en détail le processus de chargement du point de vue du Bytecode , Et comment ses principales caractéristiques sont réalisées .
Je crois qu'après avoir étudié ce chapitre ,Tu aurais raison.JVM Pour aller plus loin .
1. Class Structure du fichier
Dans les documents officiels《The Java Virtual Machine Specification-JavaSE8》C'est très détaillé.classStructure du code byte, En particulier, l'emplacement de départ du fichier , Chaque octet a un sens clair .
1.1. Class Structure du fichier Bytecode
Type | Nom | Description | Longueur | Nombre | |
---|---|---|---|---|---|
Nombre magique | u4 | magic | Nombre magique,IdentificationClassFormat du fichier,CAFEBABE | 4Octets | 1 |
Numéro de version | u2 | minor_version | Sous - version No.(Petites versions) | 2Octets | 1 |
u2 | major_version | Numéro de version principal(Grande version) | 2Octets | 1 | |
Collection de pools constants | u2 | constant_pool_count | Compteur de pool constant | 2Octets | 1 |
cp_info | constant_pool | Tableau des pools constants | nOctets | constant_pool_count - 1 | |
Identification de l'accès | u2 | access_flags | Identification de l'accès | 2Octets | 1 |
Collection Index | u2 | this_class | Index des classes | 2Octets | 1 |
u2 | super_class | Index parent | 2Octets | 1 | |
u2 | interfaces_count | Compteur d'interface | 2Octets | 1 | |
u2 | interfaces | Collection d'index d'interface | 2Octets | interfaces_count | |
Collection de tables de champs | u2 | fields_count | Compteur de champ | 2Octets | 1 |
field_info | fields | Tableau des champs | nOctets | fields_count | |
Collection de tables de méthodes | u2 | methods_count | Compteur de méthodes | 2Octets | 1 |
method_info | methods | Tableau méthodologique | nOctets | methods_count | |
Collection de feuilles de propriétés | u2 | attributes_count | Compteur d'attributs | 2Octets | 1 |
attribute_info | attributes | Feuille de propriétés | nOctets | attributes_count |
1.2. Class Type de données du fichier
Type de données | Définition | Description |
---|---|---|
Nombre non signé | Un nombre non signé peut être utilisé pour décrire un nombre、Référence de l'index、Valeur de la quantité ou selon utf-8 Valeur de la chaîne constituée par l'encodage. | Où le nombre non signé appartient au type de données de base. Par u1、u2、u4、u8 Pour représenter 1 Octets、2 Octets、4 Octets et 8 Octets |
Tableau | Un tableau est une structure de données composée de plusieurs nombres non signés ou d'autres tableaux.. | Toutes les tables sont“_info”Fin. Parce que le tableau n'a pas de longueur fixe,Il est donc souvent précédé d'une description numérique. |
1.3. Nombre magique
Magic Number(Nombre magique)
Chaque Class Au début du fichier 4 Les entiers non signés de octets sont appelés nombres magiques(Magic Number)
Sa seule fonction est de déterminer si le fichier est valide et légal pour être accepté par la machine virtuelle. Class Documentation.C'est - à - dire::Le nombre magique est Class Identifiant du fichier.
La valeur magique est fixée à 0xCAFEBABE.Ça ne changera pas.
Si un Class Le fichier n'est pas 0xCAFEBABE Au début,La machine virtuelle lance directement l'erreur suivante lors de la vérification des fichiers:
Error: A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1885430635 in class file StringTest
L'utilisation de nombres magiques plutôt que d'extensions pour l'identification est principalement basée sur des considérations de sécurité,Parce que l’extension de fichier peut être modifiée à volonté.
1.4. Numéro de version du document
Juste après le nombre magique 4 Les octets stockés sont Class Numéro de version du fichier.C'est pareil. 4 Octets.No 5 No et No. 6 Les octets signifient le numéro de sous - version compilé minor_version,Et 7 No et No. 8 Les octets sont le numéro de version principal compilé major_version.
Ensemble, ils forment class Format numéro de version du fichier.Comme un Class Le numéro de version principal du fichier est M,Le numéro de version secondaire est m,Alors, ça. Class Le numéro de version du format du fichier est déterminé comme suit: M.m.
Numéro de version et Java Les relations correspondantes pour le compilateur sont les suivantes:
Class Correspondance du numéro de version du document
Version principale(Décimal) | Sous - version(Décimal) | Version du compilateur |
---|---|---|
45 | 3 | 1.1 |
46 | 0 | 1.2 |
47 | 0 | 1.3 |
48 | 0 | 1.4 |
49 | 0 | 1.5 |
50 | 0 | 1.6 |
51 | 0 | 1.7 |
52 | 0 | 1.8 |
53 | 0 | 1.9 |
54 | 0 | 1.10 |
55 | 0 | 1.11 |
Java Le numéro de version de 45 Au début,JDK1.1 Après chaque JDK Version majeure numéro de version plus 1.Différentes versions Java Compilé par le compilateur Class La version du fichier est différente.Pour l'instant,Version supérieure Java Les machines virtuelles peuvent exécuter Class Documentation,Mais les versions inférieures Java La machine virtuelle ne peut pas exécuter un Class Documentation.Sinon JVM Va lancer java.lang.UnsupportedClassVersionError Anomalie.(Compatibilité descendante).
Dans la pratique,En raison de la différence entre l'environnement de développement et l'environnement de production,Peut causer ce problème.Donc,,Nous avons besoin de,Une attention particulière est accordée au développement de compilations JDK Dans la version et l'environnement de production JDK Si la version est cohérente.Machine virtuelle JDK La version est 1.k(k>=2)Heure,Correspondant class Format de fichier la plage de numéros de version est 45.0 - 44+k.0(Avec deux extrémités).
1.5. Collection de pools constants
Le pool constant est Class Une des zones les plus riches du fichier ,Pool constant pour Class L'analyse des champs et des méthodes dans les fichiers joue également un rôle crucial. Le pool constant agit comme un petit entrepôt , Il y a beaucoup d'informations sur la classe ,Pour ainsi dire,Le pool constant est tout Class La pierre angulaire du document.
Après le numéro de version,Suivi du nombre de pools constants,Et plusieurs entrées de table de pool constant.
Le nombre de constantes dans le pool de constantes n'est pas fixe,Il faut donc placer un élément à l'entrée du bassin constant u2 Nombre non signé de types,Représente la valeur du compteur de capacité constante du pool(constant_pool_count).Avec Java Les habitudes linguistiques chinoises sont différentes Oui.,Ce compte de capacité est basé sur 1 Au lieu de 0 Au début.
Type | Nom | Nombre |
---|---|---|
u2(Nombre non signé) | constant_pool_count | 1 |
cp_info(Tableau) | constant_pool | constant_pool_count - 1 |
Visible par le tableau ci - dessus,Class Le fichier utilise un compteur de capacité précédent(constant_pool_count)Ajouter plusieurs éléments de données consécutifs(constant_pool)Pour décrire le contenu d'un pool constant.Nous appelons cette série de données de pool constant continu un ensemble de pools constant.
Dans le tableau des pools constants,Utilisé pour stocker diverses références littérales et symboliques générées au moment de la compilation,Cette partie du contenu sera stockée dans le pool de constantes d'exécution dans la zone de méthode après le chargement de la classe
1.5.1. Compteur de pool constant
constant_pool_count(Compteur de pool constant)
Comme le nombre de pools constants n'est pas fixe,Durée courte,Il faut donc placer deux octets pour représenter la valeur du compteur de capacité du pool constant.
Valeur du compteur de capacité du bassin constant(u2 Type):De 1 C'est parti.,Indique le nombre de constantes dans le pool de constantes.C'est - à - dire: constant_pool_count=1 Indique qu'il y a un pool constant 0 Termes constants.
Demo La valeur de:
Sa valeur est 0x005d,C'est 93.Il est important de noter que,Ce n'est que93-1=92 Constante du terme.Index As Range is 1-92.Pourquoi?, C'est parce que d'habitude nous écrivons le code à partir de 0 Au début,Mais le pool constant ici est 1 C'est parti.,Parce qu'il met 0 La constante du terme est vide..Il s'agit de répondre à la nécessité d'exprimer certaines données ultérieures qui pointent vers les valeurs d'index des pools de constantes dans un cas particulier.“Ne fait référence à aucun projet de pool constant”Signification de,La valeur de l'index est disponible dans ce cas 0 Pour représenter.
Nous utilisons les commandes suivantes, Comme vous pouvez le voir, il n'y a vraiment que 92Item (s):
javap -v MethodStructTest.class
1.5.2. Tableau des pools constants
constant_pool Est une structure de table,Par 1 ~ constant_pool_count - 1 Pour l'index,Indique le nombre de termes constants suivants. Après ça, il y a la table des pools constants , Deux types principaux de constantes sont stockés :Quantité littérale(Literal)Et références symboliques(Symbolic References). Les littératures sont des chaînes de texte ou sont déclarées comme final Valeur constante pour. Les références symboliques sont “Nom complet de la classe et de l'interface”、“Nom et descripteur du champ”、“Nom et descripteur de la méthode”.
En dernier analyse,Il contient class Toutes les constantes de chaîne référencées dans la structure du fichier et ses sous - structures、Nom de la classe ou de l'interface、Nom du champ et autres constantes.Chaque élément d'un pool constant a les mêmes caractéristiques.No 1 Octets comme marqueur de type,Format utilisé pour déterminer l'élément,Cet octet s'appelle tag byte(Étiquette octet、Étiquette octets).
Cette information entre dans le pool de constantes d'exécution de la zone de méthode après le chargement du Bytecode ,C'est ça. La relation entre le pool constant d'octets et le pool constant d'exécution .
Type | Le logo(Ou identification) | Description |
---|---|---|
CONSTANT_Utf8_info | 1 | UTF-8 Chaîne encodée |
CONSTANT_Integer_info | 3 | Littéral entier |
CONSTANT_Float_info | 4 | Littéral flottant |
CONSTANT_Long_info | 5 | Long entier littéral |
CONSTANT_Double_info | 6 | Littéral flottant de double précision |
CONSTANT_Class_info | 7 | Référence symbolique d'une classe ou d'une interface |
CONSTANT_String_info | 8 | Type de chaîne littérale |
CONSTANT_Fieldref_info | 9 | Référence symbolique du champ |
CONSTANT_Methodref_info | 10 | Références symboliques aux méthodes de la classe |
CONSTANT_InterfaceMethodref_info | 11 | Référence symbolique de la méthode dans l'interface |
CONSTANT_NameAndType_info | 12 | Référence symbolique du champ ou de la méthode |
CONSTANT_MethodHandle_info | 15 | Poignée de représentation |
CONSTANT_MethodType_info | 16 | Type de méthode de marquage |
CONSTANT_InvokeDynamic_info | 18 | Représente un point d'appel de méthode dynamique |
Avant d'interpréter ces constantes,,Nous devons comprendre plusieurs concepts.
Nom completcom/test/test/Demo C'est le nom complet de la classe.,Juste le nom du sac“.“Remplacer par”/”,Afin de ne pas créer de confusion entre plusieurs noms entièrement qualifiés consécutifs,Vous finissez généralement par ajouter un“;”Indique la fin de la désignation complète.
Nom simpleUn nom simple est une méthode ou un nom de champ qui n'a pas de modificateurs de type et de paramètre, Par exemple, dans une classe add()Méthodes et num Les noms simples des champs sont respectivement add Et num.
DescripteurLe descripteur est utilisé pour décrire le type de données du champ、Liste des paramètres de la méthode(Y compris la quantité、Type et ordre)Et valeurs de retour.Selon les règles du descripteur,Type de données de base(byte、char、double、float、int、long、short、boolean)Et représentant aucune valeur de retour void Les types sont représentés par un caractère majuscule,Le type d'objet utilise des caractères L Représenté par un nom entièrement qualifié de l'objet,Voir le tableau ci - dessous pour plus de détails.:
Logo | Sens |
---|---|
B | Type de données de base byte |
C | Type de données de base char |
D | Type de données de base double |
F | Type de données de base float |
I | Type de données de base int |
J | Type de données de base long |
S | Type de données de base short |
Z | Type de données de base boolean |
V | Représentant void Type |
L | Type d'objet,Par exemple,:Ljava/lang/Object; |
[ | Type de tableau,Représente un tableau unidimensionnel.Par exemple,:`double[] is [D |
Lorsqu'un descripteur est utilisé pour décrire une méthode,Liste des premiers paramètres,Description séquentielle des valeurs de retour en arrière,La liste des paramètres est placée entre parenthèses dans l'ordre strict des paramètres“()”À l'intérieur.Comme la méthode java.lang.String tostring()Le descripteur de est()Ljava/lang/String; ,Méthodes int abc(int[]x, int y)Le descripteur de est([II)I.
Notes complémentaires:
La machine virtuelle charge Class Les fichiers ne sont pas dynamiquement liés,C'est - à - dire,Class Les informations finales de mise en page de la mémoire pour chaque méthode et champ ne sont pas sauvegardées dans le fichier.Donc,,Les références symboliques à ces champs et méthodes ne peuvent pas être utilisées directement par la machine virtuelle sans conversion.Lorsque la machine virtuelle fonctionne,Nécessite une référence symbolique correspondante du pool constant,Ensuite, il est remplacé par une référence directe pendant la phase d'analyse pendant le chargement de la classe,Et traduit dans une adresse mémoire spécifique.
La différence et l'association entre la référence symbolique et la référence directe sont décrites ici.:
Référence symbolique:Une référence symbolique décrit la cible référencée par un ensemble de symboles,Le symbole peut être n'importe quelle forme de littératie,.Tant qu'il est utilisé pour localiser la cible sans ambiguïté.Les références symboliques sont indépendantes de la disposition de la mémoire implémentée par la machine virtuelle,La cible référencée n'est pas nécessairement chargée en mémoire.
Citation directe:Une référence directe peut être un pointeur vers une cible、Un décalage relatif ou une poignée qui peut être positionnée indirectement vers la cible.La référence directe est liée à la disposition de la mémoire implémentée par la machine virtuelle,Les références directes traduites d'une même référence symbolique sur différentes instances de machines virtuelles ne sont généralement pas les mêmes.S'il y a une référence directe,Cela signifie que la cible référencée doit déjà exister en mémoire..
Ⅱ. Type et structure constants
Chaque constante d'un pool de constantes est un tableau,J0K1.7 Après 14 Différents types de données de structure de tableau.Comme indiqué dans le tableau ci - dessous:
Selon la description de chaque type dans la figure ci - dessus, nous pouvons également savoir quel type est utilisé pour décrire ce qui se trouve dans le pool constant.(Principalement littéral、Référence symbolique)De.Par exemple,: CONSTANT_Integer_info Est utilisé pour décrire l'information littérale dans un pool constant,Et c'est juste un message littéral entier.
Marqué comme suit: 15、16、18 Le type d'élément constant est utilisé pour soutenir les appels linguistiques dynamiques(jdk1.7 J'ai rejoint).
Description détaillée:
CONSTANT_Class_info Structure utilisée pour représenter une classe ou une interface
CONSTAT_Fieldref_info、CONSTAHT_Methodref_infoF Et lCONSTANIT_InterfaceMethodref_info La structure représente les champs、Fang hui et Xiao Kou fa
CONSTANT_String_info La structure est utilisée pour représenter String Objet constant de type
CONSTANT_Integer_info Et CONSTANT_Float_info Représentation 4 Octets(int Et float)Constante numérique pour
CONSTANT_Long_info Et CONSTAT_Double_info Représentation structurelle 8 Calligraphie(long Et double)Constante numérique pour
In class Dans la table de mise en commun des fichiers,Ce qui s'est passé a Les octets sont souvent empruntés par les deux membres du tableau(Item (s))Une question vide.Si un CONSTAHT_Long_info Et CNSTAHT_Double_info Le BIT d'index de la structure dans le pool constant n,Un bit d'index disponible dans le pool constant n+2,L'index dans la longueur constante du pool est n+1 L'article pour est toujours valide mais doit être considéré comme non disponible.
CONSTANT_NameAndType_info Structure utilisée pour représenter un champ ou une méthode,Mais avec le précédent 3 Les structures sont différentes,CONSTANT_NameAndType_info La structure n'indique pas la classe ou l'interface à laquelle appartient le champ ou la méthode..
CONSTANT_Utf8_info Valeur utilisée pour représenter une constante de caractère
CONSTANT_MethodHandle_info Structure utilisée pour représenter la poignée de méthode
CONSTANT_MethodType_info La structure représente le type de méthode
CONSTANT_InvokeDynamic_info Représentation structurelle invokedynamic La méthode de démarrage utilisée par la directive(bootstrap method)、Nom de l'appel dynamique utilisé pour démarrer la méthode(dynamic invocation name)、Paramètres et types de retour,Et vous pouvez passer une série de paramètres statiques à la méthode de démarrage(static argument)Constante de.
Méthode analytique:
Analyse octet par octet
Utiliser javap Résolution des commandes:javap-verbose Demo.class Ou jclasslib Les outils seront plus pratiques.
Résumé 1:
Voilà. 14 Tableau des espèces(Ou la structure des termes constants)Ce qui est commun:Le tableau commence par un u1 Bit de drapeau du type(tag),Indique quelle structure de tableau est actuellement utilisée pour cet élément constant,C'est - à - dire quel type de constante.
Dans la liste des pools constants,CONSTANT_Utf8_info Un terme constant est un terme amélioré UTF-8 Format codé pour stocker des chaînes de texte telles que、Nom complet de la classe ou de l'interface、Le nom simple du champ ou de la méthode et les informations de chaîne constantes telles que le descripteur.
Voilà. 14 Une autre caractéristique de la structure des termes constants est,Parmi eux 13 Octets fixes occupés par les éléments constants,Seulement CONSTANT_Utf8_info Octets occupés non fixés,Sa taille est déterminée par length Décide que.Pourquoi??Parce que le contenu stocké dans le pool constant,Il contient des références littérales et symboliques,Ce sera une chaîne à la fin,La taille de ces chaînes n'est déterminée qu'au moment de l'écriture du programme,Par exemple, vous définissez une classe,Les noms de classe peuvent être plus longs et plus courts,Donc avant de compiler,Taille non fixée,Après compilation,Adoption utf-8 Codage,Pour connaître sa longueur.
Résumé 2:
Pool constant:Peut être compris comme Class Entrepôt de ressources dans le fichier,C'est... Class Le type de données le plus associé à d'autres éléments dans la structure du fichier(Beaucoup des types de données suivants pointent ici),C'est aussi l'occupation. Class Un des plus grands éléments de données dans l'espace de fichier.
Pourquoi le pool constant contient - il ce contenu?Java Code en cours Javac Au moment de la compilation,Ce n'est pas comme C Et C++Il y a“Connexion”Cette étape,Au lieu de cela, chargez la machine virtuelle C1ass Lier dynamiquement les fichiers.C'est - à - dire,In Class Les méthodes individuelles ne sont pas sauvegardées dans le fichier、Informations finales sur la disposition de la mémoire pour le champ,Donc ces champs、La référence symbolique de la méthode ne peut pas obtenir une véritable adresse d'entrée de mémoire sans conversion d'exécution,Ne peut pas être utilisé directement par la machine virtuelle.Lorsque la machine virtuelle fonctionne,Nécessite une référence symbolique correspondante du pool constant,Résoudre à nouveau lors de la création ou de l'exécution de la classe、Traduit dans une adresse mémoire spécifique.À propos de la création de classes et des liens dynamiques,Expliquer plus en détail le processus de chargement des classes de machines virtuelles
1.6. Panneau d'accès
Identification de l'accès(access_flag、Panneau d'accès、Marque d'accès)
Après le pool constant,Suivi des balises d'accès.La marque est représentée par deux octets,Informations d'accès utilisées pour identifier certaines classes ou couches d'interface,Y compris::C'est Class Classe ou interface;Défini comme public Type;Défini comme abstract Type;Si c'est une classe,Est déclaré comme final Attendez..Les différentes marques d'accès sont les suivantes:
Nom du logo | Valeur du drapeau | Sens |
---|---|---|
ACC_PUBLIC | 0x0001 | Marqué comme suit: public Type |
ACC_FINAL | 0x0010 | Le logo est déclaré final,Seules les classes peuvent être définies |
ACC_SUPER | 0x0020 | Le logo est autorisé invokespecial Nouvelle sémantique de la directive Bytecode,JDK1.0.2 Le drapeau de la classe compilée plus tard est vrai par défaut.(Appeler la méthode parent en utilisant la méthode améliorée) |
ACC_INTERFACE | 0x0200 | LOGO c'est une interface |
ACC_ABSTRACT | 0x0400 | Oui Non abstract Type,Pour une interface ou une classe abstraite,La valeur du drapeau secondaire est vraie,Les autres types sont faux |
ACC_SYNTHETIC | 0x1000 | Indique que cette classe n'est pas générée par un code d'utilisateur(C'est - à - dire::Classe générée par le compilateur,Pas de code source correspondant) |
ACC_ANNOTATION | 0x2000 | LOGO c'est une annotation |
ACC_ENUM | 0x4000 | Il s'agit d'une énumération |
L'accès à la classe est généralement ACC_Constante au début.
Chaque type de représentation est marqué en définissant l'accès 32 Un bit particulier dans le BIT à implémenter.Par exemple,,Si public final La classe de,Alors la marque est ACC_PUBLIC | ACC_FINAL.
Utiliser ACC_SUPER Une façon de positionner la classe plus précisément sur la classe mère super.method(),Les compilateurs modernes configurent et utilisent cette balise.
Notes complémentaires:
Avec ACC_INTERFACE Marque class Le fichier représente une interface plutôt qu'une classe,Au lieu de cela, il s'agit d'une classe et non d'une interface.
Si un class Le fichier est défini ACC_INTERFACE Le logo,Alors il faut aussi régler ACC_ABSTRACT Le logo.Et il ne peut plus être réglé ACC_FINAL、ACC_SUPER Ou ACC_ENUM Le logo.
Si ce n'est pas réglé ACC_INTERFACE Le logo,Alors, ça. class Les fichiers peuvent avoir des divisions dans le tableau ci - dessus ACC_ANNOTATION Tous les autres signes à l'extérieur.Bien sûr.,ACC_FINAL Et ACC_ABSTRACT À l'exception de ces signes mutuellement exclusifs.Ces deux signes ne doivent pas être apposés en même temps.
ACC_SUPER Le drapeau est utilisé pour identifier invokespecial Quelle sémantique d'exécution l'instruction utilise.Pour Java Ce drapeau doit être défini par le compilateur de l'ensemble d'instructions de la machine virtuelle.Pour Java SE 8 Et les versions suivantes,Peu importe. class Quelle est la valeur réelle de ce drapeau dans le fichier,Je m'en fous. class Quel est le numéro de version du fichier,Java Les machines virtuelles pensent que chaque class Tous les fichiers sont configurés ACC_SUPER Le logo.
ACC_SUPER Le drapeau est conçu pour être rétrocompatible avec l'ancien Java Conçu à partir du Code compilé par le compilateur.En cours ACC_SUPER Le logo est affiché par JDK1.0.2 Les compilateurs précédents ont généré access_flags Il n'y a pas de sens définitif.,Si le drapeau est défini,Alors 0racle De Java L'implémentation de la machine virtuelle l'ignore.
ACC_SYNTHETIC Le drapeau signifie que la classe ou l'interface est générée par le compilateur,Plutôt que généré par le code source.
Le type d'annotation doit être défini ACC_ANNOTATION Le logo.Si défini ACC_ANNOTATION Le logo,Alors vous devez définir ACC_INTERFACE Le logo.
ACC_ENUM Le drapeau indique que la classe ou son parent est un type énuméré.
1.7. Index des classes、Index parent、Index des interfaces
Après avoir accédé à l'étiquette,Spécifie la catégorie de cette classe、Catégories de parents et interfaces implémentées,Le format est le suivant::
Longueur | Sens |
---|---|
u2 | this_class |
u2 | super_class |
u2 | interfaces_count |
u2 | interfaces[interfaces_count] |
Ces trois données déterminent l'héritage de cette classe:
L'index de classe est référencé pour déterminer le nom entièrement qualifié de cette classe
L'index parent est utilisé pour déterminer le nom entièrement qualifié de la classe parent de cette classe..Parce que Java La langue ne permet pas l'héritage multiple,Donc l'index parent n'a qu'un seul,Sauf que java.1ang.Object Au - delà,Tous les Java Toutes les classes ont des parents,Donc, à part java.lang.Object Extérieur,Tous les Java L'index parent de la classe n'est pas e.
La collection d'index d'interface est utilisée pour décrire quelles interfaces cette classe implémente,Ces interfaces implémentées seront implements Déclarations(Si la classe elle - même est une interface,Alors ça devrait être extends Déclarations)Les interfaces suivantes sont disposées de gauche à droite dans la collection Index des interfaces.
1.7.1. this_class(Index des classes)
2 Octet entier non signé,Index pointant vers le pool constant.Il fournit le nom complet de la classe,Par exemple: com/test/java1/Demo.this_class La valeur de doit être une valeur d'index valide pour un élément de la table du pool constant.Les membres du pool constant à cet index doivent être: CONSTANT_Class_info Type de structure,La structure représente ceci class Classe ou interface définie par le fichier.
1.7.2. super_class(Index parent)
2 Octet entier non signé,Index pointant vers le pool constant.Il fournit le nom entièrement qualifié de la classe mère de la classe courante.Si nous n'héritons d'aucune classe,Son héritage par défaut est java/lang/object Catégorie.En même temps,Parce que Java Plusieurs héritages ne sont pas pris en charge,Il n'y a donc qu'un seul parent..
super_class Le parent pointé ne peut pas être final.
1.7.3. interfaces
Pointer vers la collection d'index du pool constant,Il fournit une référence symbolique à toutes les interfaces implémentées
Parce qu'une classe peut implémenter plusieurs interfaces,Par conséquent, vous devez enregistrer l'index de plusieurs interfaces sous forme de tableau,Chaque index représentant l'interface est également un index pointant vers le pool constant CONSTANT_Class(Bien sûr, il doit y avoir une interface ici,Au lieu de la classe).
Ⅰ. interfaces_count(Compteur d'interface)
interfaces_count La valeur de l'élément indique le nombre de superinterfaces directes pour la classe ou l'interface courante.
Ⅱ. interfaces[](Collection d'index d'interface)
interfaces[]La valeur de chaque membre doit être une valeur d'index valide pour un élément de la table du pool constant,Sa longueur est interfaces_count.Chaque membre interfaces[i]Doit être CONSTANT_Class_info Structure,Parmi eux 0 <= i < interfaces_count.In interfaces[]Moyenne,La séquence d'interface représentée par chaque membre et la séquence d'interface donnée dans le code source correspondant(De gauche à droite)C'est pareil,C'est - à - dire: interfaces[0]Correspond à l'interface la plus à gauche du code source.
1.8. Collection de tables de champs
fields
Utilisé pour décrire les variables déclarées dans une interface ou une classe.Champ(field)Inclure les variables au niveau de la classe et de l'Instance,Mais pas à l'intérieur de la méthode、Variables locales déclarées à l'intérieur du bloc de code.
Comment s'appelle le champ、Le champ est défini pourquoi le type de données,Ils ne peuvent pas être fixés.,Seules les constantes du pool de constantes peuvent être citées pour décrire.
Il pointe vers une collection d'index de pool constant,Il décrit l'information complète pour chaque champ.Comme l'identificateur du champ、Modificateur d'accès(public、private Ou protected)、Variable de classe ou d'instance(static Modificateur)、Constante ou non(final Modificateur)Attendez..
Notes:
Les champs hérités de la classe mère ou de l'interface implémentée ne sont pas listés dans la collection de tables de champs,Mais il est possible de lister l'original Java Champs qui n'existent pas dans le Code.Par exemple, dans les classes internes, pour maintenir l'accès aux classes externes,Ajoute automatiquement un champ à une instance de classe externe.
In Java Les champs de la langue ne peuvent pas être surchargés,Type de données pour les deux champs、Modificateurs identiques ou non,Doit utiliser un nom différent,Mais pour le Bytecode,,Si les descripteurs des deux champs ne sont pas cohérents,Ce champ a un double nom légal..
1.8.1. Compteur de champ
fields_count(Compteur de champ)
fields_count La valeur de représente le courant class Documentation fields Nombre de membres du tableau.Utiliser deux octets pour représenter.
fields Chaque membre du tableau est un field_info Structure,Utilisé pour représenter tous les champs de classe ou d'instance déclarés par la classe ou l'interface,Ne comprend pas les variables déclarées à l'intérieur de la méthode,N'incluez pas non plus les champs hérités de la classe parent ou de l'interface parent.
Nom du logo | Valeur du drapeau | Sens | Nombre |
---|---|---|---|
u2 | access_flags | Panneau d'accès | 1 |
u2 | name_index | Index des noms de champs | 1 |
u2 | descriptor_index | Index des descripteurs | 1 |
u2 | attributes_count | Compteur d'attributs | 1 |
attribute_info | attributes | Collection de propriétés | attributes_count |
1.8.2. Tableau des champs
Ⅰ. ID d'accès à la table des champs
Nous savons que,Un champ peut être modifié par une variété de mots clés,Par exemple,:Modificateur de portée(public、private、protected)、static Modificateur、final Modificateur、volatile Modificateurs, etc.Donc,,Il peut ressembler au drapeau d'accès de la classe,Utilisez des drapeaux pour marquer les champs.Les drapeaux d'accès aux champs sont les suivants:
Nom du logo | Valeur du drapeau | Sens |
---|---|---|
ACC_PUBLIC | 0x0001 | Le champ est public |
ACC_PRIVATE | 0x0002 | Le champ est private |
ACC_PROTECTED | 0x0004 | Le champ est protected |
ACC_STATIC | 0x0008 | Le champ est static |
ACC_FINAL | 0x0010 | Le champ est final |
ACC_VOLATILE | 0x0040 | Le champ est volatile |
ACC_TRANSTENT | 0x0080 | Le champ est transient |
ACC_SYNCHETIC | 0x1000 | Champ généré automatiquement par le compilateur |
ACC_ENUM | 0x4000 | Le champ est enum |
Ⅱ. Index des descripteurs
Le descripteur est utilisé pour décrire le type de données du champ、Liste des paramètres de la méthode(Y compris la quantité、Type et ordre)Et valeurs de retour.Selon les règles du descripteur,Type de données de base(byte,char,double,float,int,long,short,boolean)Et représentant aucune valeur de retour void Les types sont représentés par un caractère majuscule,L'objet utilise des caractères L Représenté par un nom entièrement qualifié de l'objet,Comme suit:
Logo | Sens |
---|---|
B | Type de données de base byte |
C | Type de données de base char |
D | Type de données de base double |
F | Type de données de base float |
I | Type de données de base int |
J | Type de données de base long |
S | Type de données de base short |
Z | Type de données de base boolean |
V | Représentant void Type |
L | Type d'objet,Par exemple,:Ljava/lang/Object; |
[ | Type de tableau,Représente un tableau unidimensionnel.Par exemple,:`double[] is [[[D |
Ⅲ. Collection de feuilles de propriétés
Un champ peut aussi avoir des propriétés,Pour stocker des informations supplémentaires.Comme la valeur d'initialisation、Quelques notes d'information, etc.Nombre de propriétés stockées dans attribute_count Moyenne,Le contenu spécifique de l'attribut est stocké dans attributes Dans le tableau.
// Prenons par exemple l'attribut constant,La structure est la suivante::
ConstantValue_attribute{
u2 attribute_name_index;
u4 attribute_length;
u2 constantvalue_index;
}
Description:Pour les attributs constants,attribute_length Valeur constante 2.
1.9. Collection de tables de méthodes
methods:Pointer vers la collection d'index du pool constant,Il décrit en détail la signature de chaque méthode.
Dans le fichier Bytecode,Chaque method_info Les éléments correspondent à des informations de méthode dans une classe ou une interface.Comme le modificateur d'accès de la méthode(public、private Ou protected),Type de valeur de retour de la méthode et informations sur les paramètres de la méthode, etc..
Si cette méthode n'est pas abstraite ou n'est pas native De,Alors le code byte apparaîtra.
D'un côté,methods Le tableau ne décrit que les méthodes déclarées dans la classe ou l'interface courante.,Ne pas inclure les méthodes héritées de la classe mère ou de l'interface parent.D'un autre côté,methods Les tables peuvent avoir des méthodes ajoutées automatiquement par le compilateur,Le plus typique est l'information de méthode générée par le compilateur(Par exemple,:Catégorie(Interface)Méthode d'initialisationclinit()Et les méthodes d'initialisation des instancesinit()).
Précautions d'emploi:
In Java Dans la langue,Pour recharger(Overload)Une approche,En plus d'avoir le même nom simple que la méthode originale,Il est également nécessaire d'avoir une signature caractéristique différente de la méthode originale.,Une signature caractéristique est une collection de références de symboles de champ pour chaque paramètre d'une méthode dans un pool constant,C'est - à - dire que la valeur de retour n'est pas incluse dans la signature de la fonction,Donc, Java La langue ne peut pas surcharger une méthode existante simplement en fonction de la valeur de retour.Mais dans Class Dans le format de fichier,La signature caractéristique a une portée plus large,Deux méthodes peuvent coexister tant que le descripteur n'est pas entièrement cohérent.C'est - à - dire,Si les deux méthodes ont le même nom et la même signature caractéristique,Mais la valeur de retour est différente,Alors c'est légal de coexister dans le même class Dans le document.
C'est - à - dire,Bien que Java La spécification syntaxique ne permet pas de déclarer plusieurs méthodes dans une classe ou une interface qui signent la même méthode,Mais avec Java Les spécifications grammaticales sont opposées,Le fichier Bytecode permet de stocker plusieurs méthodes pour signer la même méthode,La seule condition est que les valeurs de retour ne peuvent pas être les mêmes entre ces méthodes.
1.9.1. Compteur de méthodes
methods_count(Compteur de méthodes)
methods_count La valeur de représente le courant class Documentation methods Nombre de membres du tableau.Utiliser deux octets pour représenter.
methods Chaque membre du tableau est un method_info Structure.
1.9.2. Tableau méthodologique
methods[](Tableau méthodologique)
methods Chaque membre du tableau doit être un method_info Structure,Description complète utilisée pour représenter une méthode dans la classe ou l'interface courante.Si un method_info Structure access_flags L'élément n'a pas été défini ACC_NATIVE Le drapeau n'est pas non plus défini ACC_ABSTRACT Le logo,Ensuite, la structure devrait également inclure les éléments utilisés pour mettre en œuvre cette approche. Java Instructions de la machine virtuelle.
method_info Les structures peuvent représenter toutes les méthodes définies dans les classes et les interfaces,Inclure des méthodes d'instance、Méthode de classe、Méthode d'initialisation de l'instance et méthode d'initialisation de la classe ou de l'interface
La structure de la table de méthode est en fait la même que celle de la table de champ,Le tableau méthodologique est structuré comme suit::
Nom du logo | Valeur du drapeau | Sens | Nombre |
---|---|---|---|
u2 | access_flags | Panneau d'accès | 1 |
u2 | name_index | Index des noms de méthodes | 1 |
u2 | descriptor_index | Index des descripteurs | 1 |
u2 | attributes_count | Compteur d'attributs | 1 |
attribute_info | attributes | Collection de propriétés | attributes_count |
Drapeau d'accès à la table de méthode
Comme pour les tables de champs,Les tables de méthodes ont également des drapeaux d'accès,Et leur logo est en partie le même,La partie est différente,Les drapeaux d'accès spécifiques pour le tableau des méthodes sont les suivants::
Nom du logo | Valeur du drapeau | Sens |
---|---|---|
ACC_PUBLIC | 0x0001 | public,La méthode est accessible en dehors du paquet |
ACC_PRIVATE | 0x0002 | private,La méthode ne peut être consultée que par cette classe |
ACC_PROTECTED | 0x0004 | protected,Les méthodes sont accessibles en elles - mêmes et dans les sous - classes |
ACC_STATIC | 0x0008 | static,Méthode statique |
1.10. Collection de feuilles de propriétés
Collection de tables de propriétés après la collection de tables de méthodes,Ça veut dire class Informations supplémentaires contenues dans le document,Comme ça. class Nom du fichier source du fichier.Et tout ce qui a RetentionPolicy.CLASS Ou RetentionPolicy.RUNTIME Notes.Ces informations sont généralement utilisées Java Validation et fonctionnement des machines virtuelles,Et Java Mise en service du programme,Il n'est généralement pas nécessaire d'en savoir plus.
En outre,Tableau des champs、Les tables de méthodes peuvent avoir leurs propres tables de propriétés.Utilisé pour décrire des informations spécifiques à certains scénarios.
Les limites de l'ensemble de feuilles de propriétés sont moins strictes,Les feuilles de propriétés individuelles ne doivent plus être strictement ordonnées,Et tant qu'il n'est pas dupliqué avec un nom de propriété existant,N'importe quel compilateur implémenté par n'importe qui peut écrire ses propres informations de propriété définies dans la Feuille de propriétés,Mais... Java La machine virtuelle ignore les attributs qu'elle ne reconnaît pas au moment de l'exécution.
1.10.1. Compteur d'attributs
attributes_count(Compteur d'attributs)
attributes_count La valeur de représente le courant class Nombre de membres de la Feuille de propriétés du fichier.Chaque élément de la Feuille de propriétés est un attribute_info Structure.
1.10.2. Feuille de propriétés
attributes[](Feuille de propriétés)
La valeur de chaque élément de la Feuille de propriétés doit être attribute_info Structure.La structure de la Feuille de propriétés est flexible,Les différents attributs ne peuvent être obtenus que s'ils satisfont à la structure suivante:.
Format commun des attributs
Type | Nom | Nombre | Sens |
---|---|---|---|
u2 | attribute_name_index | 1 | Index des noms de propriétés |
u4 | attribute_length | 1 | Longueur de l'attribut |
u1 | info | attribute_length | Feuille de propriétés |
Type de propriété
Les feuilles de propriétés peuvent en fait avoir plusieurs types,Ce que je vois là - haut Code La propriété n'est qu'une de ces,Java8 C'est défini à l'intérieur 23 Propriétés des espèces.Ce sont des propriétés prédéfinies dans la machine virtuelle:
Nom de la propriété | Position d'utilisation | Sens |
---|---|---|
Code | Tableau méthodologique | Java Instructions Bytecode compilées par Code |
ConstantValue | Tableau des champs | final Pool constant défini par mot - clé |
Deprecated | Catégorie,Méthodes,Tableau des champs | Est déclaré comme deprecated Méthodes et champs pour |
Exceptions | Tableau méthodologique | Exception lancée par la méthode |
EnclosingMethod | Fichiers de classe | Cette propriété n'est disponible que si une classe est locale ou anonyme,Cet attribut est utilisé pour identifier la méthode périphérique dans laquelle la classe réside |
InnerClass | Fichiers de classe | Liste des classes internes |
LineNumberTable | Code Propriétés | Java La relation correspondante entre le numéro de ligne du code source et l'instruction Bytecode |
LocalVariableTable | Code Propriétés | Description des variables locales de la méthode |
StackMapTable | Code Propriétés | JDK1.6 Nouvel attribut dans,Pour les nouveaux types de vérification de l'appariement des classes nécessaires pour les variables locales et les opérandes du vérificateur et de la méthode cible de traitement |
Signature | Catégorie,Tableau méthodologique,Tableau des champs | Utilisé pour soutenir les signatures de méthode dans les cas génériques |
SourceFile | Fichiers de classe | Enregistrer le nom du fichier source |
SourceDebugExtension | Fichiers de classe | Pour stocker des informations de débogage supplémentaires |
Synthetic | Catégorie,Tableau méthodologique,Tableau des champs | Drapeau généré automatiquement par la méthode ou le champ pour le compilateur |
LocalVariableTypeTable | Catégorie | Oui, c'est triste que la signature caractéristique remplace le descripteur,Est ajouté pour décrire les types paramétriques génériques après l'introduction de la syntaxe générique |
RuntimeVisibleAnnotations | Catégorie,Tableau méthodologique,Tableau des champs | Prise en charge des annotations dynamiques |
RuntimeInvisibleAnnotations | Catégorie,Tableau méthodologique,Tableau des champs | Utilisé pour indiquer quelles annotations sont invisibles à l'exécution |
RuntimeVisibleParameterAnnotation | Tableau méthodologique | Rôle et RuntimeVisibleAnnotations Propriétés similaires,Juste l'objet ou la méthode d'action |
RuntimeInvisibleParameterAnnotation | Tableau méthodologique | Rôle et RuntimeInvisibleAnnotations Propriétés similaires,Juste l'objet ou la méthode d'action |
AnnotationDefault | Tableau méthodologique | Valeurs par défaut utilisées pour enregistrer les éléments de la classe d'annotation |
BootstrapMethods | Fichiers de classe | Pour enregistrer invokeddynamic Qualificatif de méthode de démarrage référencé par la directive |
Ou(Voir le site officiel)
Détails des attributs partiels
① ConstantValue Propriétés
ConstantValue La propriété représente la valeur d'un champ constant.Situé à field_info Dans la Feuille de propriétés de la structure.
ConstantValue_attribute{
u2 attribute_name_index;
u4 attribute_length;
u2 constantvalue_index;//Index des valeurs des champs dans le pool constant,L'entrée du pool de constantes à cet index donne la valeur constante représentée par cet attribut.(Par exemple,La valeur est1ongType,Dans un pool constant, c'estCONSTANT_Long)
}
② Deprecated Propriétés
Deprecated Les propriétés sont JDK1.1 Pour soutenir les mots clés dans les [email protected] Et l'introduction.
Deprecated_attribute{
u2 attribute_name_index;
u4 attribute_length;
}
③ Code Propriétés
Code L'attribut est le code stocké dans le corps de la méthode.Mais,Tous les tableaux de méthodes n'ont pas Code Propriétés.Comme une interface ou une méthode abstraite,Ils n'ont pas de méthode spécifique,Il n'y aurait donc pas Code Propriété.Code Structure de la Feuille de propriétés,Comme le montre la figure ci - dessous::
Type | Nom | Nombre | Sens |
---|---|---|---|
u2 | attribute_name_index | 1 | Index des noms de propriétés |
u4 | attribute_length | 1 | Longueur de l'attribut |
u2 | max_stack | 1 | La profondeur maximale de la pile d'opérandes |
u2 | max_locals | 1 | Espace de survie requis pour le tableau des variables locales |
u4 | code_length | 1 | Longueur de l'instruction Bytecode |
u1 | code | code_lenth | Stocker les instructions Bytecode |
u2 | exception_table_length | 1 | Longueur anormale du tableau |
exception_info | exception_table | exception_length | Tableau des anomalies |
u2 | attributes_count | 1 | Compteur de collection d'attributs |
attribute_info | attributes | attributes_count | Collection de propriétés |
Je vois.:Code Les deux premiers éléments de la Feuille de propriétés sont conformes à la Feuille de propriétés,C'est - à - dire: Code La Feuille de propriétés suit la structure de la Feuille de propriétés,Ce sont ses structures personnalisées.
④ InnerClasses Propriétés
Pour plus de commodité, définissez spécifiquement une classe ou une interface Class Le format est C.Si C Le pool constant de CONSTANT_Class_info Membres,Et la classe ou l'interface représentée par ce membre n'appartient à aucun paquet,Alors C De ClassFile La Feuille de propriétés de la structure doit contenir le InnerClasses Propriétés.InnerClasses Les propriétés sont JDK1.1 Introduit pour soutenir les classes internes et les interfaces internes,Situé à ClassFile Feuille de propriétés de la structure.
⑤ LineNumberTable Propriétés
LineNumberTable L'attribut est un attribut optionnel de longueur variable,Situé à Code Feuille de propriétés de la structure.
LineNumberTable La propriété est utilisée pour décrire Java Correspondance entre le numéro de ligne du code source et le numéro de ligne du Code octet.Cet attribut peut être utilisé pour localiser le nombre de lignes exécutées par le Code au moment du débogage.
start_pc,C'est - à - dire le numéro de ligne du code byte;1ine_number,C'est - à - dire: Java Numéro de ligne du code source.
In Code Dans la Feuille de propriétés de la propriété,LineNumberTable Les propriétés peuvent apparaître dans n'importe quel ordre,En outre,Plusieurs LineNumberTable Les attributs peuvent représenter ensemble ce qu'un numéro de ligne représente dans le fichier source,C'est - à - dire: LineNumberTable La propriété n'a pas besoin d'une correspondance individuelle avec les lignes du fichier source.
// LineNumberTableStructure de la Feuille de propriétés:
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];
}
⑥ LocalVariableTable Propriétés
LocalVariableTable Est un attribut optionnel de longueur variable,Situé à Code Dans la Feuille de propriétés de la propriété.Il est utilisé par le débogueur pour déterminer les informations sur les variables locales de la méthode pendant l'exécution.In Code Dans la Feuille de propriétés de la propriété,LocalVariableTable Les propriétés peuvent apparaître dans n'importe quel ordre.Code Il ne peut y avoir qu'une seule variable locale par attribut LocalVariableTable Propriétés.
start pc + length Indique la position offset de cette variable au début et à la fin de son cycle de vie en Bytecode(this Cycle de vie depuis le début e À la fin 10)
index Est la fente de cette variable dans la table des variables locales(La fente peut être réutilisée)
name Est le nom de la variable
Descriptor Représente la description du type de variable locale
// LocalVariableTableStructure de la Feuille de propriétés:
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];
}
⑦ Signature Propriétés
Signature L'attribut est un attribut optionnel de longueur fixe,Situé à ClassFile,field_info Ou method_info Dans la Feuille de propriétés de la structure.In Java Dans la langue,Toutes catégories、Interface、Signature générique de la méthode d'initialisation ou du membre si elle contient une variable de type(Type Variables)Ou type paramétrique(Parameterized Types),Et Signature La propriété enregistre les informations de signature génériques pour elle.
⑧ SourceFile Propriétés
SourceFile Structure des attributs
Type | Nom | Nombre | Sens |
---|---|---|---|
u2 | attribute_name_index | 1 | Index des noms de propriétés |
u4 | attribute_length | 1 | Longueur de l'attribut |
u2 | sourcefile index | 1 | Citation du fichier source |
Je vois.,Sa longueur est toujours fixée 8 Octets.
⑨ Autres attributs
Java Les propriétés prédéfinies dans la machine virtuelle sont 20 Plusieurs,Il n'y a pas d'introduction ici,Par l'introduction des propriétés ci - dessus,Il suffit de comprendre son essence,D'autres attributs sont également faciles à interpréter.
边栏推荐
- [Chongqing Guangdong education] National Open University autumn 2018 0088-21t Insurance Introduction reference questions
- Tiktok__ ac_ signature
- Roman numeral to integer
- 傅里叶分析概述
- How can easycvr cluster deployment solve the massive video access and concurrency requirements in the project?
- Why does the C# compiler allow an explicit cast between IEnumerable&lt; T&gt; and TAlmostAnything?
- Global and Chinese market of networked refrigerators 2022-2028: Research Report on technology, participants, trends, market size and share
- 【无标题】
- Opencv judgment points are inside and outside the polygon
- VOT toolkit environment configuration and use
猜你喜欢
d3dx9_ How to repair 31.dll_ d3dx9_ 31. Solution to missing DLL
Business introduction of Zhengda international futures company
Google Maps case
一文搞定垃圾回收器
opencv 判断点在多边形内外
513. Find the value in the lower left corner of the tree
Post-90s tester: "after joining Ali, this time, I decided not to change jobs."
Tensor attribute statistics
Nanjing: full use of electronic contracts for commercial housing sales
Metasploit(msf)利用ms17_010(永恒之蓝)出现Encoding::UndefinedConversionError问题
随机推荐
Metaverse Ape获Negentropy Capital种子轮融资350万美元
Post-90s tester: "after joining Ali, this time, I decided not to change jobs."
VOT Toolkit环境配置与使用
Vcomp110.dll download -vcomp110 What if DLL is lost
Analysis of the problem that the cookie value in PHP contains a plus sign (+) and becomes a space
一文搞定class的微观结构和指令
Solutions for unexplained downtime of MySQL services
Go语言学习教程(十五)
Paddle Serving v0.9.0 重磅发布多机多卡分布式推理框架
如何创建线程
BFC block level formatting context
700. Search in a Binary Search Tree. Sol
C language - structural basis
Arduino measures AC current
點到直線的距離直線的交點及夾角
【Note17】PECI(Platform Environment Control Interface)
H5c3 advanced - player
Tensor attribute statistics
一文搞定JVM常见工具和优化策略
I closed the open source project alinesno cloud service