8.1 dynamic connection and resolution
The class file stores all its reference symbols in a constant pool. Each class file has a constant pool, and each class or interface loaded by the Java Virtual Machine has an internal version of the constant pool, called the runtime constant pool. The runtime constant pool is an implementation-specific data structure that is mapped to the constant pool in the class file. Therefore, when a type is loaded for the first time, all symbolic references from the type are loaded to the type runtime constant pool.
When the program runs at a certain time point, if a specific symbol Reference is to be used, it must be parsed first. The parsing process is to find the entity based on the symbol reference, and then replace the symbol reference with a direct reference process. Because all symbolic references are stored in the constant pool, this process is often called constant pool resolution.
Remember: the Java Virtual Machine saves an independent constant pool for each mounted class and interface.
8.1.1 resolution and Dynamic Scaling
The Java architecture allows the dynamic expansion of Java programs. This process includes the types used by the runtime, loading them, and using them. By passing the type name to the forname () method of Java. Lang. class, or the loadclass () method of the User-Defined class loader, Java programs can be dynamically expanded. Two Dynamic Scaling methods:
1) directly use the forname () method of Java. Lang. Class
Public static class forname (string classname) throwsclassnotfoundexception;
// This method uses the class loader of the current class and always initializes this type
Public satic class forname (string classname, booleaninitialize, classloader loader) throws classnotfoundexception;
// The initialize parameter can be used to specify whether Initialization is performed after loading. loader can specify the class loader to be loaded.
2) use the loadclass () method of the User-Defined Class Loader
To use a custom classloader request type, you only need to call the loadclass () method of the classloader.
Protected class loadclass (string name) throws classnotfoundexception
Protected class loadclass (string name, Boolean resolve) throwsclassnotfoundexception;
Both loadclass () Methods accept the full-qualified names of the load type to load the name parameter of the string type. In the double-parameter version of loadclass (), the Boolean Type parameter indicates whether to execute this type of connection during loading.
Difference: If there is no special requirement to use the class loader, forname () should be used. If the requested type is initialized during loading, forname () must be used (); if you need some specific loading methods, such as downloading from the network, extracting from the database, extracting from the encrypted file, or even creating them dynamically, in this case, a class loader is required.
8.1.4 constant_class_info
In the constant pool entry type, the most complicated to parse is constant_class_info.
Array class parsing:
Each array is parsed into a class instance in the Virtual Machine. If the element type of the array is a reference type, the virtual machine uses the current class loader to parse the element type. If the element type of the array is a basic type, the virtual machine immediately creates a new array class for that element type, and the dimension is determined at this time. Then, an instance of the class is created to represent this type. For referenced arrays, arrays are marked as defined by the classloader that defines their element types. For an array of basic types, the array class is marked as defined by the startup class loader.
Analysis of Non-array classes and interfaces:
Since it needs to be parsed in multiple steps, the following uses 1a to 2D to describe this process.
Step 1: as the first step of resolution, the virtual machine must determine whether the referenced type has been loaded into the current namespace. If not, the VM passes the full qualified name of the type to the current class loader.
Step 1a: load type or any supertype
For each class loader, the Java Virtual Machine maintains a list, which records the names of all its loaded types. Each such list forms the internal namespace of the Java Virtual Machine. The virtual machine uses the parent-parent Delegation Model to load the type. Once the referenced type is loaded, the virtual machine checks its binary data carefully. If the type is a class and is not Java. Lang. object, the VM obtains the full qualified name of its direct superclass based on the class data. The VM then checks whether the superclass has been loaded into the current namespace. If no, first load the superclass. Once the superclass is mounted, the virtual machine checks its binary data again to find its superclass. Until the superclass is an object. Then, on the way returned from the object, the virtual machine checks whether each type directly implements any interface. If so, it will ensure that those interfaces are also loaded. After Step 1a, the Java Virtual Machine checks whether a type is loaded and ensures that all its superclasses and all superinterfaces are loaded.
Step 1b: Check Access Permissions
If the referenced type does not have the permission to access the referenced type, the virtual machine throws an illegalaccesserror exception. The access permission check is performed before the formal verification phase.
Step 2: connect and initialize the type and any superclass
Step 2a: Check type
This step is the formal verification phase in Chapter 7. The validation phase may require the virtual machine to load new types to confirm that bytecode conforms to the semantics of the Java language.
Step 2b: Preparation type
In the preparation phase, virtual machines allocate memory for type variables and data structures (such as method tables) that vary with implementation.
Step 2c: optional steps, resolution type
Steps 1a, 2a, and 2B have resolved the consant_class_info entry of the constant pool that initiates the reference. Step 2c is about parsing the symbolic references contained in the referenced type.
Step 2D: initialization type
If the type has a superclass, the initialization type of the superclass is in the top-down order.
8.1.5 constant_fieldref_info
To resolve the constant_fieldref_info constant pool entry, the virtual machine must first parse the constant_class_info entry specified in the class_index entry. If constant_class_info is successfully parsed, the VM performs the field search process as follows:
1) the VM searches for fields with the specified name and type in the referenced type. If the VM finds such a field, this field is the result of a successful field search.
2) otherwise, the virtual machine inspection type directly implements or extends interfaces and recursively checks their interfaces. If a field with the same name and type is found, this field is the result of a successful field search.
3) Otherwise, if the type has a direct superclass, the VM checks the direct superclass of the type and recursively checks all the superclasses of the type. If the fields whose names and types match are found, this field is the result of a successful field search.
4) field search failed.
If the field is found, the virtual machine marks this entry as resolved and places a direct reference pointing to this field in the data of this constant pool entry.
8.1.6 constant_methodref_info
To resolve the constant_methodref_info constant pool entry, the VM must first parse the constant_class_info entry specified in the class_index entry. If constant_class_info is successfully parsed, the virtual machine performs the parsing following steps:
1) if the parsed type is an interface rather than a class, the VM throws incompatibleclasschangeerror
2) otherwise, the VM checks whether the referenced class has a method that complies with the specified name and descriptor. If the Virtual Machine finds such a method, this method is the result of a successful method search.
3) Otherwise, if the type has a direct superclass, the VM checks the direct superclass of the type and recursively checks all the superclass of the type to check whether a method matches the specified name and descriptor, if such a method is found, this method is the result of a successful field search.
4) otherwise, the virtual machine inspection type directly implements or extends interfaces and recursively checks their interfaces. Check whether there is a method that matches the specified name and descriptor. If such a method is found, this method is the result of a successful field search.
5) otherwise, the method search fails.
If the method is found, the virtual machine marks this entry as resolved and places the direct reference pointing to this method in the data of this constant pool entry.
8.1.8 constant_string_info
Each Java virtual machine must maintain an internal list that lists references to all string objects that have been "detained (intern)" while running the program. Basically, if a string appears on the detention list of the virtual machine, it is said to have been detained. The key to maintaining this list is that any specific character sequence appears only once in this list.
To detain the Character Sequence represented by the constant_string_info entry, the VM should check whether the character sequence on the internal detention list has been compiled. If the file has been compiled, the VM uses a reference pointing to a previously detained String object. Otherwise, the virtual machine creates a new character object based on the Character Sequence and lists the references of this object.
In Java programs, you can call the intern () method of the string class to hold a string.
8.1.11 constant parsing during compilation
It is initialized as a reference to the static final variable at the time of compilation, and is parsed as a local copy of the constant value during compilation. This applies to all basic types and Java. lang. string is correct.
There are two advantages: 1) local copy of a constant value enables the static final variable to be used in the case expression in the switch statement. 2) Conditional compilation.