Los amigos que estudian Java deben saber que Java ha estado usando el lema de la independencia de la plataforma desde el principio, diciendo "escribir una vez, ejecutar en cualquier lugar". De hecho, cuando se trata de irrelevancia, la plataforma Java tiene otra irrelevancia, que es la independencia del lenguaje. , Para lograr la independencia del lenguaje, entonces la estructura de archivos de la clase en el sistema Java o. Es muy importante decir que es código de bytes. De hecho, Java ha tenido dos conjuntos de especificaciones desde el principio, uno es la especificación del lenguaje Java y el otro es la especificación de la máquina virtual Java. La especificación del lenguaje Java solo estipula las restricciones. relacionados con el lenguaje y las reglas de Java, y las especificaciones de la máquina virtual están realmente diseñadas desde una perspectiva multiplataforma. Hoy tomaremos un ejemplo práctico para ver cómo debería verse el bytecode correspondiente a un archivo Class en Java. Este artículo primero explicará en general en qué consiste el contenido de la clase y luego utilizará una clase Java real para analizar la estructura de archivos de la clase.
Antes de continuar, primero debemos aclarar los siguientes puntos:
1) Los archivos de clase se componen de flujos de bytes de 8 bytes. Estos flujos de bytes están estrictamente organizados en el orden especificado y no hay espacios entre bytes. Para archivos que superen los 8 bytes, los datos se almacenarán en orden Big-Endian. es decir, el byte de orden superior se almacena en la dirección baja y el byte de orden inferior se almacena en la dirección alta. Esta es también la clave para los archivos de clase multiplataforma, porque la arquitectura PowerPC usa el orden de almacenamiento Big-Endian, mientras que los procesadores de la serie x86 usan el orden de almacenamiento Little-Endian, por lo que para que los archivos de clase se mantengan en cada arquitectura de procesador Almacenamiento unificado En orden, las especificaciones de la máquina virtual deben estar unificadas.
2) La estructura del archivo de clase utiliza una estructura similar al lenguaje C para almacenar datos. Hay dos tipos principales de elementos de datos: números sin signo y tablas, que se utilizan para expresar números, referencias de índice y cadenas, como u1, u2. , u4 y u8 representan 1 byte, 2 bytes, 4 bytes y 8 bytes de números sin signo respectivamente, y la tabla es una estructura compuesta compuesta por múltiples números sin signo y otras tablas. Tal vez todos aquí no tengan muy claro qué son los números y tablas sin signo, pero no importa, lo explicaré con ejemplos cuando dé los ejemplos a continuación.
Después de aclarar los dos puntos anteriores, echemos un vistazo a los datos específicos contenidos en el flujo de bytes organizados en orden estricto en el archivo de clase:
Al mirar la imagen de arriba, hay una cosa a la que debemos prestar atención, como cp_info. cp_info representa el grupo constante. En la imagen de arriba, constante_pool [constant_pool_count-1] se usa para representar el grupo constante con constante_pool_co. constante unt-1, aquí se expresa en forma de matriz, pero no piense erróneamente que las longitudes constantes de todos los grupos constantes son las mismas. De hecho, este lugar utiliza el método de matriz solo por conveniencia de descripción, pero. no es así. En los lenguajes de programación, una matriz de tipo int tiene la misma longitud que cada int. Después de aclarar este punto, miremos hacia atrás y veamos qué representa específicamente cada elemento en la imagen de arriba.
1) u4 magic representa el número mágico y el número mágico ocupa 4 bytes. En realidad, significa que el tipo de archivo es un archivo Class, no una imagen JPG o una película AVI. El número mágico correspondiente al archivo Class es 0xCAFEBABE.
2) u2 minor_version representa el número de versión menor del archivo de clase, y este número de versión es una representación numérica sin signo del tipo u2.
3) u2 major_version representa el número de versión principal del archivo de clase, y el número de versión principal es una representación numérica sin signo del tipo u2. major_version y minor_version se utilizan principalmente para indicar si la máquina virtual actual acepta la versión actual del archivo de clase. Las versiones de los archivos Class compilados por diferentes versiones de compiladores Java son diferentes. Una versión superior de la máquina virtual admite la estructura de archivos de clase compilada por una versión inferior del compilador. Por ejemplo, la máquina virtual correspondiente a Java SE 6.0 admite la estructura de archivos de clase compilada por el compilador Java SE 5.0, pero no al revés.
4) u2 constante_pool_count representa el número de grupos constantes. Aquí debemos centrarnos en qué es el grupo de constantes. No lo confunda con el grupo de constantes de tiempo de ejecución en el modelo de memoria Jvm. El grupo de constantes en el archivo de clase almacena principalmente literales y referencias de símbolos, donde los literales incluyen principalmente cadenas. valor de la constante final o O el valor inicial de un determinado atributo, etc., mientras que las referencias a símbolos almacenan principalmente los nombres completos de clases e interfaces, nombres y descriptores de campos, nombres y descriptores de métodos. Los nombres aquí pueden ser fáciles de entender para todos, en cuanto a. concepto de descriptores, hablaremos de ello más adelante cuando analicemos la tabla de campos y la tabla de métodos. Además, todo el mundo sabe que el modelo de memoria de Jvm consta de montón, pila, área de método y contador de programa, y hay un área en el área de método llamada grupo de constantes de tiempo de ejecución. Las cosas almacenadas en el grupo de constantes de tiempo de ejecución son en realidad el. Inmortalidad del compilador. Varios literales y referencias de símbolos, pero el grupo de constantes de tiempo de ejecución es dinámico. Puede agregarle otras constantes en tiempo de ejecución. El más representativo es el método interno de String.
5) cp_info representa el grupo constante, que contiene los diversos literales y referencias de símbolos mencionados anteriormente. Hay un total de 14 elementos de datos colocados en el grupo de constantes en la especificación de máquina virtual Java Java SE 7 Edition. Cada constante es una tabla y cada constante utiliza una etiqueta parcial común para indicar de qué tipo es.
Los detalles específicos se describen brevemente a continuación y los perfeccionaremos en ejemplos posteriores.
El indicador de etiqueta CONSTANT_Utf8_info es 1, la cadena codificada en UTF-8 CONSTANT_Integer_info indicador de etiqueta es 3, el indicador de etiqueta CONSTANT_Float_info literal entero es 4, el indicador de etiqueta CONSTANT_Long_info literal de punto flotante es 5, el indicador de etiqueta CONSTANT_Double_info literal entero largo El bit es 6, el indicador de etiqueta CONSTANT_Class_info literal de doble precisión es 7, La referencia simbólica de la etiqueta CONSTANT_String_info de la clase o interfaz es 8, la etiqueta literal CONSTANT_Fieldref_info del tipo de cadena es 9, la referencia simbólica de la etiqueta CONSTANT_Methodref_info del campo es 10, la referencia simbólica del método en la etiqueta de clase CONSTANT_InterfaceMethodref_info es 11, simbólica referencia al método en la interfaz etiqueta CONSTANT_NameAndType_info Bit de bandera 12, nombres de campos y métodos, y referencias simbólicas a tipos
6) u2 access_flags representa la información de acceso de la clase o interfaz, como se muestra en la siguiente figura:
7) u2 this_class representa el índice del grupo constante de la clase y apunta a la constante de CONSTANT_Class_info en el grupo constante
8) u2 super_class representa el índice de la superclase y apunta a la constante de CONSTANT_Class_info en el grupo de constantes
9) u2 interface_counts representa el número de interfaces
10) La interfaz u2 [interface_counts] representa la tabla de interfaz, cada elemento en ella apunta a la constante CONSTANT_Class_info en el grupo de constantes
11) u2 campos_count representa el número de variables de instancia y variables de clase de la clase
12) field_info campos [fields_count] representa la información de la tabla de campos, donde la estructura de la tabla de campos se muestra a continuación:
En la figura anterior, access_flags representa la representación de acceso del campo. Por ejemplo, el campo es público, privado y protegido. etc., name_index representa el nombre del campo, que apunta a la constante de tipo CONSTANT_UTF8_info en el grupo de constantes, descriptor_index representa el descriptor del campo, que también apunta a la constante de tipo CONSTANT_UTF8_info en el grupo de constantes, atributos_count representa el número de tablas de atributos en la tabla de campos y la tabla de atributos Es una estructura extensible que se utiliza para describir campos, métodos y atributos de clase. Las diferentes versiones de la máquina virtual Java admiten diferentes números de tablas de atributos.
13) u2 métodos_count representa el número de tablas de métodos
14) Method_info representa la tabla de métodos. La estructura específica de la tabla de métodos se muestra en la siguiente figura:
Entre ellos, access_flags representa la representación de acceso del método, name_index representa el índice del nombre, descriptor_index representa el descriptor del método, atributos_count y atributo_info son similares a las tablas de atributos en la tabla de campos, excepto que los atributos en la tabla de atributos en la tabla de campos y la tabla de métodos son diferentes, como El atributo Código en la tabla de métodos representa el código del método, pero no hay ningún atributo Código en la tabla de campos. Cuantos atributos hay en una clase específica se discutirá más adelante cuando veamos la tabla de atributos en la estructura del archivo de clase.
15) atributo_count representa el número de tablas de atributos. Cuando se trata de tablas de atributos, debemos aclarar los siguientes puntos:
La tabla de atributos existe al final de la estructura del archivo de Clase, en la tabla de campos, la tabla de métodos y el atributo de Código. Es decir, la tabla de atributos también puede existir en la tabla de atributos. La longitud de la tabla de atributos no es fija. Diferentes atributos tienen diferentes longitudes.
Después de describir la composición de cada elemento en la estructura del archivo de Clase anterior, utilizamos un ejemplo práctico para explicar el siguiente contenido.
Copie el código de código de la siguiente manera:
paquete com.ejushang.TestClass;
la clase pública TestClass implementa Super{
privado estático final int staticVar = 0;
varinstanciaintprivado=0;
método de instancia int público (int parámetro) {
devolver parámetro+1;
}
}
interfaz Súper{ }
La estructura binaria de TestClass.class correspondiente a TestClass.java compilado mediante javac de jdk1.6.0_37 se muestra en la siguiente figura:
A continuación, analizaremos el flujo de bytes en la figura anterior en función de la estructura de archivos de Class mencionada anteriormente.
1) Número mágico <br/>De la estructura del archivo de Class, sabemos que los primeros 4 bytes son el número mágico. En la imagen de arriba, el contenido de la dirección 00000000h-00000003h es el número mágico. podemos conocer el número mágico del archivo de clase. El número es 0xCAFEBABE.
2) Números de versión mayor y menor <br/>Los siguientes 4 bytes son los números de versión mayor y menor. En la figura anterior, podemos ver que los números correspondientes de 00000004h-00000005h son 0 × 0000, por lo que la versión menor de la clase. es 0 × 0000, y el contenido correspondiente de 00000006h-00000007h es 0 × 0032, por lo que la versión major_version del archivo Class es 0 × 0032, que es exactamente la versión mayor y menor correspondiente a la Clase compilada por jdk1.6.0 sin el parámetro objetivo.
3) El número de grupo constante <br/>Los siguientes 2 bytes representan el número de grupo constante de 00000008h-00000009h. De la figura anterior, podemos saber que su valor es 0 × 0018, que es 24 en decimal, pero para. Es necesario aclarar el número de grupos de constantes. El número de grupos de constantes es constante_pool_count-1. La razón por la que se reduce en uno es porque el índice 0 significa que los elementos de datos de la clase no hacen referencia a ninguna constante en el grupo de constantes.
4) Grupo de constantes <br/>Dijimos anteriormente que hay diferentes tipos de constantes en el grupo de constantes. Echemos un vistazo a la primera constante de TestClass.class. Sabemos que cada constante está representada por un identificador de etiqueta de tipo u1. El tipo de constante, en 0000000ah en la imagen de arriba. El contenido es 0x0A, que se convierte al sistema secundario es 10. De la descripción anterior del tipo de constante, se puede ver que la constante con la etiqueta 10 es Constant_Methodref_info, y la estructura de Constant_Methodref_info se muestra en la siguiente figura:
Entre ellos, class_index apunta a la constante de tipo CONSTANT_Class_info en el grupo de constantes. Se puede ver en la estructura del archivo binario de TestClass que el valor de class_index es 0 × 0004 (la dirección es 0000000bh-0000000ch), lo que significa que apunta a. la cuarta constante.
name_and_type_index apunta a la constante de tipo CONSTANT_NameAndType_info en el grupo de constantes. Como se puede ver en la figura anterior, el valor de name_and_type_index es 0 × 0013, lo que significa que apunta a la constante número 19 en el grupo de constantes.
A continuación, puede utilizar el mismo método para encontrar todas las constantes en el grupo de constantes. Sin embargo, JDK proporciona una herramienta conveniente que nos permite ver las constantes contenidas en el grupo de constantes. Puede obtener todas las constantes en el grupo de constantes a través de javap -verbose TestClass. La captura de pantalla es la siguiente:
En la imagen de arriba, podemos ver claramente que hay 24 constantes en el grupo de constantes en TestClass. No olvide la constante 0, porque la constante 0 se usa para indicar que los elementos de datos en Class no hacen referencia a ninguna constante en la clase. piscina constante. Del análisis anterior, sabemos que el primer método de representación constante de TestClass es que la cuarta constante señalada por class_index es java/lang/Object, y el decimonoveno valor constante señalado por name_and_type_index es <init>:()V. Se puede ver aquí que la primera constante que representa un método representa el método constructor de instancia generado por el compilador de Java. Otras constantes del grupo de constantes se pueden analizar de la misma manera. Bien, después de analizar el grupo constante, analicemos a continuación access_flags.
5) u2 access_flags representa información de acceso sobre clases o interfaces. Por ejemplo, Class representa si es una clase o una interfaz, si es pública, estática, final, etc. El significado del indicador de acceso específico se mencionó anteriormente. Echemos un vistazo al indicador de acceso de TestClass. El indicador de acceso de Clase es de 0000010dh-0000010e y el valor es 0 × 0021. Según los bits de indicador de varios indicadores de acceso mencionados anteriormente, podemos saber: 0 × 0021 = 0 × 0001 | 0 × 0020, es decir, ACC_PUBLIC y ACC_SUPER son Verdaderos, ACC_PUBLIC es fácil de entender y ACC_SUPER es un indicador que llevarán las clases compiladas después de jdk1.2.
6) u2 this_class representa el valor de índice de la clase, que se utiliza para representar el nombre completo de la clase. El valor de índice de la clase se muestra en la siguiente figura:
Como se puede ver claramente en la figura anterior, el valor del índice de clase es 0 × 0003, que corresponde a la tercera constante del grupo de constantes. A través del resultado de javap, sabemos que la tercera constante es una constante del tipo CONSTANT_Class_info. del cual podemos conocer todos los detalles de la clase. El nombre calificado es: com/ejushang/TestClass /TestClass.
7) u2 super_class representa el valor de índice de la clase principal de la clase actual. El valor del índice apunta a una constante de tipo CONSTANT_Class_info en el grupo de constantes. El valor del índice de la clase principal se muestra en la siguiente figura. 0 × 0004. Verifique las primeras cuatro constantes del grupo de constantes. Se puede ver que el nombre completo de la clase principal de TestClass es: java/lang/Object.
8) interfaces_count e interfaces [interfaces_count] representan el número de interfaces y cada interfaz específica. El número de interfaces y las interfaces de TestClass se muestran en la figura siguiente, donde 0 × 0001 significa que el número de interfaces es 1 y 0 ×. 0005 significa el índice de la interfaz en el valor del grupo constante, busque la quinta constante en el grupo constante, su tipo es CONSTANT_Class_info y su valor es: com/ejushang/TestClass/Super
9) campos_count y field_info , campos_count representa el número de tablas field_info en la clase, y field_info representa las variables de instancia y variables de clase de la clase. Cabe señalar aquí que field_info no incluye los campos heredados de la clase principal. field_info es como se muestra en la siguiente figura:
Entre ellos, access_flags representa el indicador de acceso del campo, como público, privado, protegido, estático, final, etc. El valor de access_flags se muestra en la siguiente figura:
Entre ellos, name_index y descriptor_index son valores de índice del grupo constante, que representan respectivamente el nombre del campo y el descriptor del campo. El nombre del campo es fácil de entender, pero cómo entender el descriptor del campo. ¿campo? De hecho, en la especificación JVM, los descriptores de campo se especifican como se muestra en la siguiente figura:
Entre ellos, todos deben prestar atención a la última línea de la imagen de arriba. Representa el descriptor de una matriz unidimensional. El descriptor de String[][] será [[ Ljava/lang/String, y la descripción de. int[][] El símbolo es [[I. Los siguientes atributos_count y atributos_info representan el número de tablas de atributos y tablas de atributos respectivamente. Tomemos el TestClass anterior como ejemplo y echemos un vistazo a la tabla de campos de TestClass.
Primero, echemos un vistazo a la cantidad de campos. La cantidad de campos en TestClass se muestra en la siguiente figura:
Como se puede ver en la imagen de arriba, TestClass tiene dos campos. Al observar el código fuente de TestClass, podemos ver que de hecho solo hay dos campos. A continuación, veamos el primer campo. private int staticVar, cuya representación binaria en el archivo de clase se muestra a continuación:
Entre ellos, 0x001A representa el indicador de acceso. Al observar la tabla access_flags, podemos saber que son ACC_PRIVATE, ACC_STATIC, ACC_FINAL. A continuación, 0 × 0006 y 0 × 0007 representan la sexta y séptima constante en el grupo de constantes. Al observar el grupo constante, podemos saber que sus valores son: staticVar e I, donde staticVar es el nombre del campo e I es el descriptor del campo. A través de la explicación anterior de los descriptores, lo que describo es una variable de tipo int. A continuación, 0 × 0001 representa el número de tablas de atributos en la tabla de campos staticVar. En la figura anterior, se puede ver que hay 1 tabla de atributos correspondiente. al campo staticVar 0 × 0008 representa la octava constante en el grupo de constantes. Al observar el grupo de constantes, puede ver que este atributo es el atributo ConstantValue y el formato del atributo ConstantValue se muestra en la siguiente figura:
Entre ellos, atributo_name_index expresa el índice del grupo constante del nombre del atributo. En este ejemplo, es ConstantValue. El atributo_longitud de ConstantValue tiene una longitud fija de 2 y constanteValue_index representa la referencia en el grupo constante. ×0009 Puedes ver la novena constante. Ya sabes, representa una constante de tipo CONSTANT_Integer_info cuyo valor es 0.
Habiendo dicho que private static final int staticVar=0, hablemos de private intstanceVar=0 de TestClass. En este ejemplo, la representación binaria destanceVar se muestra en la siguiente figura:
Entre ellos, 0 × 0002 significa que la marca de acceso es ACC_PRIVATE, 0x000A significa el nombre del campo, que apunta a la décima constante en el grupo de constantes. Al observar el grupo de constantes, puede saber que el nombre del campo es instanciaVar. 0× 0007 representa el descriptor del campo, que apunta a la séptima constante en el grupo de constantes. Al observar el grupo de constantes, puede saber que la séptima constante es I, que representa el tipo de instanciaVar. Finalmente, 0 × 0000 representa el. El número de tablas de atributos es 0. .
10) metodos_count y metodos_info , donde metodos_count representa el número de métodos y metodos_info representa la tabla de métodos, donde la estructura de la tabla de métodos se muestra en la siguiente figura:
Como se puede ver en la figura anterior, las estructuras de método_info y campo_info son muy similares. Todos los bits de bandera y valores de acceso_flag en la tabla de métodos se muestran en la siguiente figura:
Entre ellos, name_index y descriptor_index representan el nombre y el descriptor del método, y son índices que apuntan al grupo constante respectivamente. Aquí necesitamos explicar el descriptor del método. La estructura del descriptor del método es: (lista de parámetros) valor de retorno. Por ejemplo, el descriptor de public intstanceMethod(int param) es: (I) I, lo que significa que tiene un int. parámetro de tipo Y el valor de retorno también es un método de tipo int. El siguiente es el número de atributos y la tabla de atributos. Aunque la tabla de métodos y la tabla de campos tienen el número de atributos y la tabla de atributos, los atributos que contienen son. diferente. A continuación, echemos un vistazo a la representación binaria de la tabla de métodos usando TestClass. Primero, echemos un vistazo a la cantidad de tablas de métodos. La captura de pantalla es la siguiente:
Como se puede ver en la figura anterior, el número de tablas de métodos es 0 × 0002, lo que significa que hay dos métodos. A continuación, analicemos el primer método. Primero veamos access_flag, name_index y descriptor_index del primer método. La captura de pantalla es la siguiente:
De la figura anterior, podemos saber que access_flags es 0 × 0001. De la descripción anterior del indicador access_flags, podemos ver que el valor de access_flags del método es ACC_PUBLIC y el name_index es 0x000B. La undécima constante, sabiendo que el nombre del método es <init>, 0x000C significa descriptor_index significa la duodécima constante en el grupo de constantes y su valor es () V, lo que significa que el método <init> no tiene parámetros ni valor de retorno. De hecho, este es el compilador. Métodos constructores de instancias generados automáticamente. El siguiente 0 × 0001 indica que la tabla de métodos del método <init> tiene 1 atributo. La captura de pantalla del atributo es la siguiente:
Como se puede ver en la figura anterior, la constante en el grupo de constantes correspondiente a 0x000D es Código, que representa el atributo Código del método. Entonces, aquí todos deben entender que los códigos del método se almacenan en el atributo Código del atributo. table en la tabla de métodos del archivo Class. A continuación analizamos el atributo Código. La estructura del atributo Código se muestra en la siguiente figura:
Entre ellos, atributo_name_index apunta a la constante cuyo valor es Código en el grupo de constantes, y la longitud de atributo_longitud indica la longitud de la tabla de atributos de Código (cabe señalar que la longitud no incluye la longitud de 6 bytes de atributo_nombre_índice y atributo_longitud ).
max_stack representa la profundidad máxima de la pila. La máquina virtual asigna la profundidad de los operandos en el marco de la pila en función de este valor en tiempo de ejecución, y max_locals representa el espacio de almacenamiento de la tabla de variables locales.
La unidad de max_locals es slot, que es la unidad más pequeña para que la máquina virtual asigne memoria para variables locales. En tiempo de ejecución, los tipos de datos que no superan los 32 bits, como byte, char, int, etc., ocupan 1. ranura, mientras que doble y largo Un tipo de datos de 64 bits necesita asignar 2 ranuras. Además, el valor de max_locals no es la suma de la memoria requerida por todas las variables locales, porque las ranuras se pueden reutilizar cuando la variable local excede su alcance. El espacio ocupado será reutilizado.
code_length representa el número de instrucciones de código de bytes y el código representa instrucciones de código de bytes. De la figura anterior, podemos saber que el tipo de código es u1. El valor de un tipo u1 es 0 × 00-0xFF y el decimal correspondiente es 0-. 255. Actualmente, la especificación de la máquina virtual ha definido más de 200 instrucciones.
excepción_table_length y excepción_table representan respectivamente la información de excepción correspondiente al método.
atributos_count y atributo_info representan el número de atributos y la tabla de atributos en el atributo Código, respectivamente. Desde aquí se puede ver que la tabla de atributos es muy flexible en la estructura de archivos de Clase. Puede existir en el archivo de clase, la tabla de métodos y el campo. tabla y atributo de código.
A continuación, continuamos analizando el ejemplo anterior. En la captura de pantalla del atributo Código del método init anterior, podemos ver que la longitud de la tabla de atributos es 0 × 00000026, el valor de max_stack es 0 × 0002 y el valor. de max_locals es 0 × 0001, la longitud de code_length es 0x0000000A, luego 00000149h- 00000152h es el código de bytes. A continuación, la longitud de excepción_table_length es 0 × 0000 y el valor de atributo_count es 0 × 0001. El valor de 00000157h-00000158h es 0x000E, que representa el nombre del atributo en el grupo constante. para obtener el 14. El valor de la constante es LineNumberTable, LineNu. mberTable se utiliza para describir la correspondencia entre el número de línea del código fuente de Java y el número de línea del código de bytes. No es un atributo obligatorio en tiempo de ejecución. Si cancela la generación de esta información a través del parámetro del compilador -g:none, se producirá el mayor impacto. be Cuando ocurre una excepción, el número de línea de error no se puede mostrar en la pila y los puntos de interrupción no se pueden establecer de acuerdo con el código fuente durante la depuración. A continuación, echemos un vistazo a la estructura de LineNumberTable, como se muestra a continuación:
Entre ellos, atributo_name_index se mencionó anteriormente y representa el índice del grupo constante, atributo_longitud representa la longitud del atributo y las tablas start_pc y line_number representan el número de línea del código de bytes y el número de línea del código fuente. El flujo de bytes de la propiedad LineNumberTable en este ejemplo se muestra a continuación:
Después de analizar el primer método de TestClass anterior, podemos analizar el segundo método de TestClass de la misma manera. La captura de pantalla es la siguiente:
Entre ellos, access_flags es 0 × 0001, name_index es 0x000F y descriptor_index es 0 × 0010. Al observar el grupo constante, puede saber que este método es el método público intstanceMethod (int param). A través de un método similar al anterior, podemos saber que el atributo Código de método de instancia es como se muestra en la siguiente figura:
Finalmente, analicemos los atributos del archivo de clase. De 00000191h-00000199h es la tabla de atributos en el archivo de clase, donde 0 × 0011 representa el nombre del atributo. Mirando el grupo constante, podemos saber que el nombre del atributo es SourceFile. Echemos un vistazo a la estructura de SourceFile de la siguiente manera, como se muestra en la figura:
Entre ellos, atributo_length es la longitud del atributo y sourcefile_index apunta a la constante en el grupo de constantes cuyo valor es el nombre del archivo de código fuente. En este ejemplo, la captura de pantalla del atributo SourceFile es la siguiente:
Entre ellos, atributo_length es 0 × 00000002, lo que significa que la longitud es de 2 bytes y el valor de sourcefile_index es 0 × 0012. Al observar la constante número 18 en el grupo de constantes, puede saber que el nombre del archivo de código fuente es TestClass. .Java
Finalmente, espero que los amigos interesados en la tecnología puedan comunicarse más. Weibo personal: (http://weibo.com/xmuzyq)