Note source: Silicon Valley JVM full tutorial, one million playback, the whole network peak (Song Hongkang detailed Java virtual machine)
Synchronous update: https://gitee.com/vectorx/NOT…
https://codechina.csdn.net/qq…
https://github.com/uxiahnan/N…
[toc]
1. Class file structure
## 1.1. Class byte code file structure
type | The name of the | instructions | The length of the | The number of | |
---|---|---|---|---|---|
The magic number | u4 | magic | The magic number identifies the Class file format | 4 bytes | 1 |
The version number | u2 | minor_version | Minor version number (Minor version) | 2 bytes | 1 |
u2 | major_version | Major version number (large version) | 2 bytes | 1 | |
Constant pool set | u2 | constant_pool_count | Constant pool counter | 2 bytes | 1 |
cp_info | constant_pool | Constant pool table | N bytes | constant_pool_count – 1 | |
Access to identify | u2 | access_flags | Access to identify | 2 bytes | 1 |
The index set | u2 | this_class | Class index | 2 bytes | 1 |
u2 | super_class | Index of the parent class | 2 bytes | 1 | |
u2 | interfaces_count | Interface counter | 2 bytes | 1 | |
u2 | interfaces | Interface index set | 2 bytes | interfaces_count | |
Field table set | u2 | fields_count | Field counter | 2 bytes | 1 |
field_info | fields | Field in the table | N bytes | fields_count | |
Method table set | u2 | methods_count | Method counter | 2 bytes | 1 |
method_info | methods | Method table | N bytes | methods_count | |
Property sheet collection | u2 | attributes_count | Attribute counter | 2 bytes | 1 |
attribute_info | attributes | Property sheet | N bytes | attributes_count |
1.2. Class file data types
The data type | define | instructions |
---|---|---|
Unsigned number | Unsigned numbers can be used to describe numbers, index references, quantitative values, or string values that are encoded in UTF-8. | The unsigned number is the basic data type. U1, U2, U4 and U8 represent 1 byte, 2 bytes, 4 bytes and 8 bytes respectively |
table | A table is a composite data structure composed of unsigned numbers or other tables. | All tables end with “_info”. Since the table has no fixed length, it is usually preceded by a numerical description. |
1.3. The magic number
3. Magic Number
- The unsigned 4-byte integer at the beginning of each Class file is called the Magic Number.
- Its only purpose is to determine whether the file is a valid and valid Class file that can be accepted by the virtual machine. The magic number is the identifier of the Class file.
- The magic value is fixed at 0xCAFEBABE. It won’t change.
- If a Class file does not begin with 0xCAFEBABE, the virtual machine will throw the following error when verifying the file:
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
- Using magic numbers instead of extensions for identification is mainly for security reasons, since file extensions can be changed at will.
1.4. File version number
The next four bytes of the magic number store the version number of the Class file. Again, four bytes. The fifth and sixth bytes represent the minor_version minor of the compilation, while the seventh and eighth bytes represent the major_version major of the compilation.
Together, they form the format version number of the class file. For example, if a Class file has a major version number M and a minor version number M, then the format version number of the Class file is determined to be M.M.
The correlation between the version number and the Java compiler is shown in the following table:
1.4.1. Relation of Class file version number
Major version (decimal) | Minor version (decimal) | Compiler version |
---|---|---|
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 version numbers start at 45, and each major release of the JDK after JDK1.1 is incremented by 1.
<mark> Different versions of the Java compiler compile different versions of the Class file. Currently, higher-level Java VMs can execute Class files generated by lower-level compilers, but lower-level Java VMs cannot execute Class files generated by higher-level compilers. Otherwise the JVM throws Java. Lang. UnsupportedClassVersionError anomalies. (backwards compatible) </mark>
In practical application, the difference between development environment and production environment may lead to the occurrence of this problem. Therefore, we need to pay special attention to whether the compiled version of the JDK is consistent with the version of the JDK in the production environment.
- When the virtual machine JDK version is 1.k (k>=2), the corresponding class file format version number ranges from 45.0-44 +k.0 (including both ends).
1.5. Constant pool collection
The constant pool is one of the richest areas in a Class file. Constant pools are also crucial for field and method parsing in Class files.
With the continuous development of the Java Virtual Machine, the content of constant pools is becoming more and more abundant. You can say that the constant pool is the cornerstone of the entire Class file.
Following the version number is the number of constant pools and a number of constant pool entries.
The number of constants in a constant pool is not fixed, so you need to place an unsigned number of type U2 at the entrance of a constant pool that represents the constant pool capacity count (constant_pool_count). Unlike the Java language convention, this capacity count starts at 1 instead of 0.
type | The name of the | The number of |
---|---|---|
U2 (unsigned number) | constant_pool_count | 1 |
Cp_info (table). | constant_pool | constant_pool_count – 1 |
As you can see from the table above, the Class file describes the contents of the constant pool in the form of a front capacity counter (constant_pool_count) and a number of contiguous data items (constant_pool). We refer to this series of continuous constant pool data as a constant pool collection.
- < Mark > constant pool entry
, used to store the various < Mark > literals
and < Mark > symbol references
generated at compile time, which will be stored in the < Mark > run-time constant pool
in the method area after the class is loaded
1.5.1. Constant pool counter
Constant_pool_count (constant pool counter)
- Since the number of constant pools is variable and the duration is short, two bytes need to be placed to represent the constant pool volumetric value.
- Constant pool volumeter value (U2 type) : starts at 1 , indicating how many constants there are in the constant pool. That is, constant_pool_count=1 means there are zero constant entries in the constant pool.
- The value of Demo is:
Its value is 0x0016, which is 22 by pinching. It’s important to note that this is actually only 21 constants. The index for the range is 1-21. Why is that?
Normally we write code that starts at 0, but here the constant pool starts at 1 because it leaves the 0th constant blank. This is to satisfy the need to express the meaning of “not referring to any constant pool item” for some later data that points to the constant pool index value, which can be represented by the index value 0.
1.5.2. Constant pool table
Constant_pool is a table structure indexed from 1 to constant_pool_count – 1. Indicates how many constant terms follow.
The constant pool contains two main classes of constants: <mark> literals </mark> and <mark> Symbolic References </mark bb3
It contains all string constants, class or interface names, field names, and other constants referenced in the class file structure and its substructures. Each entry in the constant pool has the same characteristics. The first byte serves as the type tag to determine the format of the item, which is called the Tag byte.
type | Mark (or mark) | describe |
---|---|---|
CONSTANT_Utf8_info | 1 | UTF-8 encoded string |
CONSTANT_Integer_info | 3 | Integer literals |
CONSTANT_Float_info | 4 | Floating point literals |
CONSTANT_Long_info | 5 | Long literals |
CONSTANT_Double_info | 6 | Double precision floating-point literals |
CONSTANT_Class_info | 7 | Symbolic reference to a class or interface |
CONSTANT_String_info | 8 | String type literals |
CONSTANT_Fieldref_info | 9 | Symbolic reference to the field |
CONSTANT_Methodref_info | 10 | Symbolic reference to a method in a class |
CONSTANT_InterfaceMethodref_info | 11 | Symbolic reference to a method in an interface |
CONSTANT_NameAndType_info | 12 | Symbolic reference to a field or method |
CONSTANT_MethodHandle_info | 15 | Represents a method handle |
CONSTANT_MethodType_info | 16 | Flag method type |
CONSTANT_InvokeDynamic_info | 18 | Represents a dynamic method call point |
Ⅰ. Literals and symbolic references
Before we can interpret these constants, we need to clear up a few concepts.
The constant pool contains two main classes of constants: literals and Symbolic References. The following table:
constant | Concrete constant |
---|---|
literal | Text string |
Constant value declared final | |
Symbolic reference | Fully qualified names for classes and interfaces |
The name and descriptor of the field | |
The name and descriptor of the method |
Fully qualified name
Com/atguigu /test/Demo This is the fully qualified name of the class. It simply replaces the “. “in the package name with”/”. In order to avoid confusion between successive fully qualified names, it is usually used with a “;” Ends the fully qualified name.
The simple name
A simple name is a method or field name that has no type or parameter decoration. In the example above, the simple names of the class’s add() method and the num field are add and num, respectively.
The descriptor
The <mark> descriptor is used to describe the data type of the field, the parameter list of the method (number, type, and order), and the return value </mark>. According to the descriptor rules, basic data types (byte, char, double, float, int, long, short, Boolean) and void types that represent no return value are represented by an uppercase character, while object types are represented by the character L plus the fully qualified name of the object, as shown in the table below:
identifier | meaning |
---|---|
B | The basic data type byte |
C | The basic data type CHAR |
D | The basic data type double |
F | The basic data type float |
I | The basic data type is int |
J | The basic data type long |
S | The basic data type is short |
Z | The base data type Boolean |
V | Represents a void type |
L | Object types, such as:Ljava/lang/Object; |
[ | Array type, representing a one-dimensional array. Double [] is [D |
When a descriptor is used to describe a method, it is described in the order of the parameter list followed by the return value. The parameter list is placed within a set of braces “()” in the exact order of the parameters. For example, the descriptor of the java.lang.string tostring() method is ()Ljava/lang/String; Int ABC (int[]x, int y) = ([II)I;
Additional Notes:
The virtual machine is not dynamically linked until the Class file is loaded, that is, the final memory layout information for the various methods and fields is not stored in the Class file. Therefore, symbolic references to these fields and methods cannot be directly used by the virtual machine without conversion. < mark > when virtual during, need corresponding symbols referenced from constant pool, and then replace it in the process of class loading phase for reference directly, and translated in to a specific memory address < / mark >.
Here are the differences and associations between symbolic and direct references:
- Symbolic reference: Symbolic reference describes the referenced target with the set of symbols . Symbols can be literals in any form, as long as they can be used to unambiguously locate the target. The symbol reference is independent of the memory layout implemented by the virtual machine . The target of the reference is not necessarily loaded into memory.
- Direct reference: A direct reference can be a direct pointer to the target, a relative offset, or a handle that can be indirectly located to the target. The direct reference is the associated with the memory layout implemented by the virtual machine. The same symbolic reference will not translate the same direct reference on different virtual machine instances. If there is a direct reference, the target of the reference must already exist in memory.
Ⅱ. Constant types and structures
Each constant in the constant pool is a table, and there are 14 different table structure data after J0K1.7. As shown in the table below:
From the description of each type in the figure above we can also see what each type is used to describe in the constant pool (mainly literals, symbolic references). For example, CONSTANT_Integer_info is used to describe literal information in a constant pool, and only integer literal information.
Constant item types marked 15, 16, 18 are used to support dynamic language calls (added in JDK 1.7).
Details:
- The CONSTANT_Class_info structure is used to represent a class or interface
- The CONSTAT_Fieldref_info, CONSTAHT_Methodref_infoF, and lCONSTANIT_InterfaceMethodref_info structures represent fields, squares, and cliches
- The CONSTANT_String_info structure is used to represent a constant object of type String
- CONSTANT_Integer_info and CONSTANT_Float_info represent 4-byte numeric constants (int and float)
-
The CONSTANT_Long_info and CONSTAT_Double_info structures represent numeric constants of the characters 8 (long and double)
- In the constant-most pool table of a class file, a byte constant-borrow in a row occupies the empty space of two table members. If a CONSTAHT_Long_info and CNSTAHT_Double_info are in the constant pool, then one available bit in the constant pool is n+2. The entries with an index of n+1 in the constant pool are still valid but must be considered unavailable.
- The CONSTANT_NameAndType_info structure is used to represent a field or method, but unlike the previous three structures, it does not specify the class or interface to which the field or method belongs.
- CONSTANT_Utf8_info is used to represent the value of a character constant
- The CONSTANT_MethodHandle_info structure is used to represent the method handle
- The constant_methodType_info structure represents the method type
- The CONSTANT_InvokeDynamic_info structure represents the bootstrap method and the dynamic invocation name for the invokedynamic command Name, parameters, and return type, and you can pass a series of constants called static arguments to the bootstrap method.
Analytical method:
- Parsing byte by byte
- It is more convenient to use the javap command: javap-verbose Demo. Class or the jclasslib tool.
Conclusion 1:
- What these 14 tables (or constant-item structures) have in common is that the first bit of the table is a U1-type tag, which indicates which table structure is currently being used for the constant item.
- In the constant pool list, the CONSTANT_Utf8_info constant entry is a modified UTF-8 encoding format that stores constant string information such as literal strings, fully qualified names of classes or interfaces, simple names of fields or methods, and descriptors.
- Another feature of these 14 constant entries is that 13 of them have a fixed byte size, while only CONSTANT_Utf8_info has a variable byte size, which is determined by length. Why is that? < mark > because, from the content of the constant pool to store its storage is literal and symbolic references, eventually the content can be a string, the string is in write a program to determine the size of the < / mark >, for example, you define a class, the class name can take short take long, so before didn’t compile, size is not fixed, compiled, By UTF-8 encoding, you know the length.
Conclusion 2:
- Constant pool: Think of as a resource repository within a Class file. It is the data type most associated with other items in the Class file structure (many of the following data types will point to this), and it is also one of the data items that occupies the largest space in a Class file.
- Why do you want to include this in a constant pool? Java code does not have a “join” step when compiling Javac as C and C++ do. Instead, it is dynamically linked when the virtual machine loads the C1ASS file. That is to say, “mark > in the Class file will not keep the final memory layout of each method, field information, so these fields, methods, symbolic references without the run-time transformation cannot get real memory entry address, also cannot be directly used by the virtual machine < / mark >. When the virtual machine runs, it needs to get the corresponding symbol reference from the constant pool, which is then parsed and translated into the specific memory address at class creation time or runtime. The creation and dynamic linking of classes will be explained in more detail during the virtual machine class loading process
1.6. Access flags
Access flag (access_flag, access flag, access flag)
After the constant pool, the access tag is followed. This tag is represented by two bytes that identify some Class or interface level access information, including: whether the Class is a Class or an interface; Whether to define a public type; Whether to define an abstract type; If it is a class, is it declared final, etc. The various access flags are as follows:
Sign the name | Flag values | meaning |
---|---|---|
ACC_PUBLIC | 0x0001 | The flag is of type public |
ACC_FINAL | 0x0010 | The flag is declared final and only the class can be set |
ACC_SUPER | 0x0020 | The flag allows the use of the new semantics of the InvokeSpecial bytecode instruction and defaults to true for classes compiled after JDK1.0.2. Invoking superclass methods with enhanced methods |
ACC_INTERFACE | 0x0200 | Indicates that this is an interface |
ACC_ABSTRACT | 0x0400 | If it is of type abstract, the secondary flag value is true for an interface or abstract class and false for any other type |
ACC_SYNTHETIC | 0x1000 | Indicates that this class is not generated by user code (i.e., a compiler generated class with no source code counterpart) |
ACC_ANNOTATION | 0x2000 | Flags This is a comment |
ACC_ENUM | 0x4000 | Flag that this is an enumeration |
Class access permissions are usually constants starting with ACC_.
Each type of representation is achieved by setting a specific bit in the 32 bits of the access tag. For example, if the public final class, the marked ACC_PUBLIC | ACC_FINAL.
Using ACC_SUPER allows the class to more accurately locate the super.method() method of the superclass, and modern compilers set and use this flag.
Additional Notes:
-
A class file with the ACC_INTERFACE flag represents an interface, not a class; otherwise, a class, not an interface.
- If a class file is set with the ACC_INTERFACE flag, then the ACC_ABSTRACT flag must also be set. It can no longer set the ACC_FINAL, ACC_SUPER, or ACC_ENUM flags.
- If the ACC_INTERFACE flag is not set, then the class file can have all the flags in the table above except the ACC_ANNOTATION flag. Except, of course, for mutex flags such as ACC_FINAL and ACC_ABSTRACT. The two flags must not be set at the same time.
-
The ACC_Super flag is used to determine which execution semantics are used for an InvokeSpecial directive within a class or interface. <mark> Compilers for the Java Virtual Machine instruction set should set this flag </mark>. For Java SE 8 and later versions, the Java Virtual Machine assumes that each class file is set with the ACC_SUPER flag, regardless of the actual value of this flag in the class file and regardless of the version number of the class file.
- The ACC_SUPER flag is designed for backward compatibility with code compiled by older Java compilers. The current ACC_SUPER flag has no defined meaning in access_flags generated by compilers prior to JDK1.0.2 and is ignored by the Java Virtual Machine implementation of 0racle if it is set.
- The ACC_SYNTHETIC flag means that the class or interface is generated by the compiler rather than the source code.
- The annotation type must set the ACC_ANNOTATION flag. If the ACC_ANNOTATION flag is set, then the ACC_INTERFACE flag must also be set.
- The ACC_ENUM flag indicates that the class or its parent is an enumerated type.
1.7. Class index, superclass index, interface index
After the tag is accessed, the class category, the parent class category, and the interface implemented are specified in the following format:
The length of the | meaning |
---|---|
u2 | this_class |
u2 | super_class |
u2 | interfaces_count |
u2 | interfaces[interfaces_count] |
These three pieces of data determine the class’s inheritance:
- The class index is used to determine the fully qualified name of the class
- The superclass index is used to determine the fully qualified name of the superclass of this class. Because the Java language does not allow multiple inheritance, there is only one parent index, and all Java classes except java.1ang.Object have a parent class, so all Java classes except java.lang.Object have a parent index that is not E.
- The set of interface indexes that describes which interfaces the class implements are arranged from left to right in the order of interfaces after the implements statement (extends if the class itself is an interface).
1.7.1. this_class (class index)
A 2-byte unsigned integer pointing to the index of the constant pool. It provides the fully qualified name of the class, such as com/atguigu/java1/Demo. The value of this_class must be a valid index value for an entry in the constant pool table. The member of the constant pool at this index must be a structure of type CONSTANT_Class_info, which represents the class or interface defined by the class file.
1.7.2. super_class (parent index)
A 2-byte unsigned integer pointing to the index of the constant pool. It provides the fully qualified name of the parent class of the current class. If we do not inherit any classes, the default is the Java /lang/ Object class. Also, because Java does not support multiple inheritance, there is only one parent class.
The super_class refers to a parent class that cannot be final.
1.7.3. interfaces
Pools to the constant pool index collection, which provides a symbolic reference to all implemented interfaces
Since a class can implement more than one interface, you need to store the indexes of multiple interfaces in an array, and each index of the interface is also a CONSTANT_Class pointing to the constant pool (of course, this has to be the interface, not the class).
Ⅰ. Interfaces_count (interface counter)
The value of the interfaces_count entry represents the number of direct superinterfaces for the current class or interface.
Ⅱ. Interfaces [] (collection of interface indexes)
The value of each member in interfaces[] must be a valid index to an entry in the constant pool table with the length interfaces_count. Each member interfaces[I] must be a CONSTANT_Class_info structure, where 0 <= I < interfaces_count. In interfaces[], each member represents the same order of interfaces given in the corresponding source code (from left to right); that is, interfaces[0] correspond to the leftmost interface in the source code.
1.8. Field Table Collection
fields
Used to describe variables declared in an interface or class. Fields include <mark> class level variables and </mark> instance level variables, but do not include local variables declared inside methods or code blocks.
The name of the field and the data type of the field is defined are not fixed and can only be described by referring to constants in the constant pool.
It points to the constant pool index collection, which describes the complete information for each field. Such as <mark> field identifier, access modifier (public, private, or protected), is it a class variable or an instance variable (static modifier), is it a constant (final modifier) </mark>, etc.
Note:
- The fieldlist collection does not list fields inherited from a parent class or implemented interface, but it may list fields that do not exist in the original Java code. For example, fields that point to instances of the outer class are automatically added to the inner class to maintain access to the outer class.
- In the Java language, fields cannot be overloaded. Two fields must have different names for their data types and modifiers, regardless of whether they are the same. However, in terms of bytecode, if the descriptors of two fields do not match, then it is legal for fields to have the same name.
1.8.1. Field Counter
Fields_count (field counter)
The value FIELDS_COUNT represents the number of members in the FIELDS table of the current class file. Use two bytes to represent.
Each member in the FIELDS table is a FIELD_INFO structure that represents all of the class fields or instance fields declared by the class or interface, excluding variables declared inside the method or fields that are inherited from the parent class or interface.
Sign the name | Flag values | meaning | The number of |
---|---|---|---|
u2 | access_flags | Access tokens | 1 |
u2 | name_index | Field name index | 1 |
u2 | descriptor_index | Descriptor index | 1 |
u2 | attributes_count | Attribute counter | 1 |
attribute_info | attributes | Attribute set | attributes_count |
1.8.2. Field in the table
Ⅰ. Field table access identification
We know that a field can be modified with a variety of keywords, such as scope modifier (public, private, protected), static modifier, final modifier, volatile modifier, and so on. Therefore, it can be used to mark fields with flags just like the access flags of a class. Field access flags are as follows:
Sign the name | Flag values | meaning |
---|---|---|
ACC_PUBLIC | 0x0001 | Whether the field is public |
ACC_PRIVATE | 0x0002 | Whether the field is private |
ACC_PROTECTED | 0x0004 | Whether the field is protected |
ACC_STATIC | 0x0008 | Whether the field is static or not |
ACC_FINAL | 0x0010 | Whether the field is final |
ACC_VOLATILE | 0x0040 | Whether the field is volatile |
ACC_TRANSTENT | 0x0080 | Whether the field is transient |
ACC_SYNCHETIC | 0x1000 | Whether the field is automatically generated by the compiler |
ACC_ENUM | 0x4000 | Whether the field is enum |
Ⅱ. Descriptor index
The descriptor is used to describe the data type of the field, the list of arguments to the method (including number, type, and order), and the return value. According to the descriptor rules, the primitive data types (byte, char, double, float, int, long, short, Boolean) and void types that represent no return value are represented by an uppercase character, while objects are represented by the character L plus the fully qualified name of the object, as follows:
identifier | meaning |
---|---|
B | The basic data type byte |
C | The basic data type CHAR |
D | The basic data type double |
F | The basic data type float |
I | The basic data type is int |
J | The basic data type long |
S | The basic data type is short |
Z | The base data type Boolean |
V | Represents a void type |
L | Object types, such as:Ljava/lang/Object; |
[ | Array type, representing a one-dimensional array. Double [][][] is [[[D |
Ⅲ. Collection of property sheets
A field may also have properties that can be used to store additional information. Such as initialization values, some comment information, etc. The number of attributes is stored in attribute_count, and the specific content of attributes is stored in the Attributes array.
// For a constant attribute, the structure is: constantValue_attribute {u2 attribute_name; u4 attribute_length; u2 constantvalue_index; }
Note: For a constant attribute, the attribute_length value is always 2.
1.9. Method table collection
Methods: Points to the constant pool index collection, which fully describes the signature of each method.
- In the bytecode file, each method_info entry corresponds to method information in a class or interface. Such as the access modifier (public, private, or protected) of the method, the return value type of the method, and the parameter information of the method.
- If the method is not abstract or native, it will show up in the bytecode.
- On the one hand, the Methods table only describes methods declared in the current class or interface and does not include methods inherited from a parent class or interface. On the other hand, the methods table may have methods added automatically by the compiler, most typically by compiler-generated method information (such as class (interface) initialization method
() and instance initialization method
()).
Notes for use:
In the Java language, to overloaded (phrase), a method, in addition to simple with the original method with the same name, also requires must have a sign with the original method of different characteristics, characteristics of the signature is a method of each parameter in the constant pool collection referenced by the field symbol, is because the return value does not include among the characteristics of the signature, Therefore, there is no way in the Java language to override an existing method based solely on the difference in return value. In the Class file format, however, the range of signature features is wider and two methods can coexist as long as the descriptors are not exactly the same. That is, if two methods have the same name and signature but return different values, they can legally coexist in the same class file.
That is, while the Java syntax specification does not allow multiple methods with the same method signature to be declared in a class or interface, the bytecode file, contrary to the Java syntax specification, does allow multiple methods with the same method signature, provided that the return value between the methods is not the same.
1.9.1. Method counters
Methods_count (method counter)
The value methods_count represents the number of members in the methods table of the current class file. Use two bytes to represent.
Each member of the methods table is a method_info structure.
1.9.2. Method table
Methods [] (Table of Methods)
Each member in the Methods table must be a method_info structure that represents a complete description of a method in the current class or interface. If the access_flags item of a method_info structure has neither the ACC_NATIVE nor the ACC_ABSTRACTS flag set, then the structure should also contain the Java virtual machine directives used to implement the method.
The method_info structure can represent all methods defined in a class and interface, including instance methods, class methods, instance initialization methods, and class or interface initialization methods
The structure of the method table is actually the same as the field table. The structure of the method table is as follows:
Sign the name | Flag values | meaning | The number of |
---|---|---|---|
u2 | access_flags | Access tokens | 1 |
u2 | name_index | Method name index | 1 |
u2 | descriptor_index | Descriptor index | 1 |
u2 | attributes_count | Attribute counter | 1 |
attribute_info | attributes | Attribute set | attributes_count |
Method table access flags
Like field tables, method tables also have access flags, and some of their flags are the same, but some are different. The specific access flags for method tables are as follows:
Sign the name | Flag values | meaning |
---|---|---|
ACC_PUBLIC | 0x0001 | Public, methods can be accessed from outside the package |
ACC_PRIVATE | 0x0002 | Private, methods can only be accessed by the class |
ACC_PROTECTED | 0x0004 | Protected, methods that are accessible within themselves and subclasses |
ACC_STATIC | 0x0008 | Static, static method |
1.10. Collection of property sheets
The property sheet collection following the method table collection, <mark> refers to the auxiliary information </mark> carried by the class file, such as the name of the class file’s source file. And any annotations with RetentionPolicy.class or RetentionPolicy.Runtime. This information is typically used to validate and run Java virtual machines, as well as to debug Java programs. <mark> generally requires no in-depth understanding of </mark>.
In addition, field tables and method tables can have their own property tables. Used to describe information that is specific to certain scenarios.
Property sheet collections are less restrictive in that they no longer require strict ordering of individual property sheets, and any compiler implemented by anyone can write its own defined property information to a property sheet as long as it does not duplicate existing property names, but the Java Virtual Machine will ignore properties that it does not recognize at runtime.
1.10.1. Attribute Counter
Attributes_count (attribute counter)
The value of attributes_count represents the current number of members of the class file’s property sheet. Each entry in the property sheet is an attribute_info structure.
1.10.2. Property sheet
Attributes []
The value of each item in the property sheet must be an attribute_info structure. The structure of the property sheet is more flexible, as long as the following structure is satisfied for various different properties.
A common format for properties
type | The name of the | The number of | meaning |
---|---|---|---|
u2 | attribute_name_index | 1 | Attribute name index |
u4 | attribute_length | 1 | Attribute length |
u1 | info | attribute_length | Property sheet |
Attribute types
There are actually many types of property sheets, and the Code property seen above is just one of them. There are 23 properties defined in Java8. These are the predefined properties in the virtual machine:
The attribute name | Use location | meaning |
---|---|---|
Code | Method table | Bytecode instructions compiled from Java code |
ConstantValue | Field in the table | The pool of constants defined by the final keyword |
Deprecated | Class, method, field list | Methods and fields declared as Deprecated |
Exceptions | Method table | The exception thrown by the |
EnclosingMethod | The class file | This property is only available if a class is local or anonymous, and is used to identify the method surrounding the class |
InnerClass | The class file | Inner class list |
LineNumberTable | Code attributes | The line number of the Java source code corresponds to the bytecode instructions |
LocalVariableTable | Code attributes | The local variable description of the method |
StackMapTable | Code attributes | New properties in JDK1.6 that allow new type checks to match classes that are needed to handle local variables and operands of the target method |
Signature | Class, method table, field table | Used to support method signatures when generic |
SourceFile | The class file | Record the name of the source file |
SourceDebugExtension | The class file | Used to store additional debugging information |
Synthetic | Class, method table, field table | Flags a method or field that is automatically generated by the compiler |
LocalVariableTypeTable | class | The feature signature, instead of the descriptor, was added to describe generic parameterized types after the introduction of generic syntax |
RuntimeVisibleAnnotations | Class, method table, field table | Provides support for dynamic annotations |
RuntimeInvisibleAnnotations | Class, method table, field table | Used to indicate which annotations are not visible at runtime |
RuntimeVisibleParameterAnnotation | Method table | Role similar to RuntimeVisibleAnnotations attributes, only the function object or method |
RuntimeInvisibleParameterAnnotation | Method table | Role similar to RuntimeInvisibleAnnotations attributes, only the function object or method |
AnnotationDefault | Method table | Used to record the default value of an annotation class element |
BootstrapMethods | The class file | The bootstrap method qualifier used to hold references to the invokeddynamic directive |
Or (check out the website)
Part of the attribute details
1) ConstantValue properties
The constantValue property represents the value of a constant field. In the property table of the field_info structure.
ConstantValue_attribute{ u2 attribute_name_index; u4 attribute_length; u2 constantvalue_index; // The index of the field value in the constant pool. The entries in the constant pool at that index give the constant value represented by the property. (for example, if the value is of type 1ong, it would be CONSTANT_Long in the constant pool)}
(2) Deprecated attribute
The Deprecated attribute was introduced in JDK1.1 to support the @deprecated keyword in annotations.
Deprecated_attribute{
u2 attribute_name_index;
u4 attribute_length;
}
(3) Code attributes
The Code property is the Code that holds the body of the method. However, not all method tables have a Code attribute. Like interfaces or abstract methods, they have no concrete method body and therefore no Code property. The structure of the Code property sheet is as shown below:
type | The name of the | The number of | meaning |
---|---|---|---|
u2 | attribute_name_index | 1 | Attribute name index |
u4 | attribute_length | 1 | Attribute length |
u2 | max_stack | 1 | The maximum depth of the operand stack |
u2 | max_locals | 1 | The existence space required for the local variable scale |
u4 | code_length | 1 | The length of a bytecode instruction |
u1 | code | code_lenth | Stores bytecode instructions |
u2 | exception_table_length | 1 | Abnormal table length |
exception_info | exception_table | exception_length | Exception table |
u2 | attributes_count | 1 | Attribute set counter |
attribute_info | attributes | attributes_count | Attribute set |
As you can see, the first two items of the Code property sheet are the same as the property sheet, that is, the Code property sheet follows the structure of the property sheet, and the last items are the structure of the Code property sheet.
(4) InnerClasses attribute
For the sake of illustration, define a Class to represent a Class or interface in C format. If C’s constant pool contains a CONSTANT_Class_info member representing a class or interface that does not belong to any package, then the property sheet of C’s ClassFile structure must contain the corresponding innerClasses attribute. The innerClasses attribute was introduced in JDK1.1 to support InnerClasses and internal interfaces, and is a property sheet in a ClassFile structure.
(5) LineNumberTable properties
The LineNumberTable property is an optional variable-length property located in the Code structure’s property sheet.
The LineNumberTable property is <mark>, which describes the correspondence between the Java source line number and the bytecode line number </mark>. This property can be used to locate the number of lines of code executed during debugging.
- Start_pc, which is the bytecode line number; 1INE_NUMBER, which is the Java source line number.
The LineNumberTable property can appear in any order in the Code property’s property sheet. In addition, multiple LineNumberTable properties can collectively represent what a line number represents in the source file, meaning that the LineNumberTable property does not need to correspond to the source file’s lines.
// LineNumberTable structure: 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]; }
6 LocalVariableTable properties
LocalVariableTable is an optional variable-length property located in the property sheet of the Code property. It is used by the debugger to determine information about local variables during method execution. The LocalVariableTable properties can appear in any order in the Code property’s property sheet. Each local variable in the Code attribute can have at most one LocalVariableTable attribute.
- Start PC + length represents the offset position at which this variable’s life cycle begins and ends in the bytecode (this life cycle starts E to end 10).
- Index is the slot of this variable in the local variable scale (slot reusable)
- Name is the name of the variable
- Descriptor denotes a local variable type description
// LocalVariableTable attribute structure: 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]; }
All landowners Signature properties
The Signature property is an optional fixed-length property located in a ClassFile, field_info, or method_info structure property sheet. In the Java language, the Signature property records the generic Signature information for any class, interface, initializer, or member that contains Type Variables or Parameterized Types.
Today SourceFile properties
SourceFile attribute structure
type | The name of the | The number of | meaning |
---|---|---|---|
u2 | attribute_name_index | 1 | Attribute name index |
u4 | attribute_length | 1 | Attribute length |
u2 | sourcefile index | 1 | Source file element cited |
As you can see, the length is always a fixed 8 bytes.
⑨ Other attributes
There are more than 20 predefined properties in the Java Virtual Machine (JVM), and I won’t cover them all here. With the introduction of a few properties above, other properties are easy to read once you get the essence of them.