Java class loading mechanism - class loading process (to resolve)

The whole process of the Java virtual machine loads classes include: loading, validation, preparation, resolution, initialization. Validation, preparation, called to resolve the connection process. Today we talk about resolution.

Parsing stage is a virtual machine to process the constant pool of symbolic references replaced by a direct reference to the symbol reference appears to CONSTANT_Class_info, CONSTANT_Fieldref_info, CONSTANT_Methodref_info and other types of constants in the class file, parses that stage, we said there is a direct reference and symbolic references What relevance do?

  • Symbol references: a reference line with a target set of symbols described in the referenced, literal symbols may be in any form, can be unambiguous target as long as the target can be used. Symbol reference has nothing to do with the memory layout to achieve a virtual machine, because the goal is not necessarily a reference has been loaded into memory. Various virtual machine implementation of memory layout may vary, but they must be able to accept symbolic references are the same, because the literal form of symbolic references clearly defined in the java virtual machine specification of the class file format.
  • Direct references: a direct reference may be direct pointer to the object, a relative offset or indirectly targeted to handle targets. And is a direct reference to the memory layout of the virtual machine implementation of relevant references translated in a different virtual machine instances are generally not the same as a direct reference to a symbol. If you have a direct reference to that target reference must already exist in memory.

(Personal understanding: analytic symbolic reference is to become direct reference to why is that the object is to get loaded into memory, "a direct reference may be direct pointer to the target, a relative offset or indirectly positioning.?. target to handle ", that means that the object has been loaded into memory because the definition of the handle is: the only identifies the current object here to say what is the purpose of parsing stage, then it should say the next occurrence of time-resolved and the resolution is how to do a)

Virtual Machine Specification No predetermined resolution phase occurring a specific time, only requires the implementation anewarray, checkcast, getfield, getstatic, instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, multianewarray, new, putfield and putstatic that 16 before a bytecode instruction operation for the reference symbols, the first symbol parsing they use . So virtual machine implementation can be judged in the end it is when the class loader is loaded on to a symbolic constant pool references to parse, or wait until a symbolic reference will only be used to resolve before he needed.

The command corresponding to the operation are:
anewarray, multianewarray: Creating an array
checkcast, instanceof: type checking class instance
getfield, getstatic, putfield, putstatic: Access Class field (static field, otherwise known as class variables) and instance fields (non-static field , otherwise known as instance variables)
invokeinterface: call interface methods, he searches for a realization at runtime object of this interface method, find the appropriate method call
invokespecial: call some examples of methods that require special handling, including the instance initialization method , private methods and super method
invokestatic: calling a class method (static method)
invokevirtual: call object instance method, dispatching (dispatch virtual method) based on the actual type of the object, which is the most common java language assignment mode
invokedynamic: for a dynamic resolution method at runtime call site referenced qualifiers, and executes change method
ldc: a constant is loaded into the instruction operand stack
ldc_w: a constant is loaded into the instruction operand stack
new: creating instances of

(Personal understanding: when the execution of these 16 operations, first of symbols they use to parse, "they use the symbol" means that class or interface such as new when Person, Person is the symbol used this time. Person should be resolved)

A symbolic reference to the same multiple resolution request is a very common thing, the invokedynamic instructions, your virtual machine implementation can be cached (directly referenced in the record runtime constant pool of the results of the first resolution, and the constant identification as parsed state) so as to avoid the analysis operation is repeated. Whether or not actually perform the analysis operation several times, the virtual machine needs to ensure that: in the same entity, if successfully parsed before a symbolic reference, the reference to subsequent requests should have been resolved successfully; Similarly, if the first second resolution fails, then the other instructions to resolve the request for this symbol should receive the same exception.

For invokedynamic, the above rule does not hold. When it comes to a previously triggered by invokedynamic instruction through symbolic references resolved, it does not mean that the analysis results also take effect for the other invokedynamic instructions. Because the purpose of invokedynamic originally designated for dynamic language support, he cited the corresponding called "dynamic call site qualifier", "dynamic" means this is actually running the program must wait until the time of this instruction, the work can be resolved . In contrast, the remaining commands can trigger resolved are "static", can be resolved when the loading phase has just been completed, has not yet begun to execute code.

The main analysis operation for the class or interface, fields, methods class, interface method, type method, and calls the method handle 7 points class qualifiers for symbolic references, corresponding to seven kinds of constants their constant pool types. This article speaks in front of four.

First, the class or interface parsing
of Hypothesis which the current code is D, if we want a parsed never resolve symbolic references to N directly reference a class or interface C, then the virtual machine to complete the parsing process requires three steps:

  1. If the type is not an array C that virtual machine is the fully qualified name represents N transmitted to the D class loader to load the class C. In the loading process types, since metadata validation, the bytecode verification needs may trigger the loading operation of the other classes, such as loading the class parent class or implement. Once the loading process there has been any exception resolution process failed.
  2. If C is a type of an array, and the array element type is the object descriptor is N will be similar "Ljava / lang / Inter" forms, which will load the array element type according to the rules of the first point. If N descriptors, as previously assumed, and the elements need to load type is "java.lang.inter", then generates an array of objects by the virtual machine and the dimensions of this array of elements representative.
  3. If the above steps do not appear any exception, then C has actually become a valid class or interface in a virtual machine, but also for verification of symbolic references, D confirm whether they have access to the C prior to completion of the analysis. If you find that do not have access to, will throw "lava.lang.IlldgalAccessError" abnormal

Personal understanding is as follows:
When we define personaa in the main, main class loader will go to load the Person class, it may also be loaded Person of the parent class (if any). If there is no error or exception, then the Person is actually inside the virtual machine will have a valid class, but also for symbolic references to verify, confirm whether they have access to D C before the completion of the analysis. If multiple new Person, then resolve not repeated often because the amount of the pool will run in direct reference to record this symbol, and the constant identified as resolved state.

public class Person {
	public String clientName;
	public String clientId;

	public String getClientName() {
		return clientName;
	}

	public void setClientName(String clientName) {
		this.clientName = clientName;
	}

	public String getClientId() {
		return clientId;
	}

	public void setClientId(String clientId) {
		this.clientId = clientId;
	}
}

public class Main {
	public static void main(String args[]){
		Person personaa = new Person();
	}
}

Second, the field is parsed
to resolve unresolved over a field of symbolic references, first of all in the field will be on the table class_index entry in the index CONSTANT_Class_info symbolic references to parse, that is the symbol of the field belongs to the class or interface references. If there are any anomalies in the process of parsing the class or interface symbols cited, the field will result in failure to resolve the symbolic references. If the resolution is completed successfully, it will belong to the class or interface of this field is represented by C, C Virtual Machine Specification requirements for subsequent search field following procedure.

  1. If C itself contains a simple field names and field descriptors are matched with the target, this field is returned direct reference to find the end;
  2. Otherwise, if implemented in the C interface will follow up the inheritance recursively search each interface and the interface from his father, if the interface contains the field names and field descriptors are simple and objective matches Returns direct reference to this field, to find the end;
  3. Otherwise, if C is not java.lang.Object, it will follow up the inheritance from the parent class recursive search, if the parent class contains a simple field names and field descriptors are matched to the target, then return to this direct reference field and look for the end;
  4. Otherwise, the lookup fails, an exception is thrown java.lang.NoSuchFieldError.

If the search returns a reference to the process is successful, it will be on the field to verify permissions, if found not to have access to the field, java.lang.IllegalAccessError will throw an exception.
In practice, the virtual machine compiler implementation may be more stringent than the number of regulatory requirements, if there is a field of the same name also appear in the C interface and the parent class, or multiple interfaces simultaneously in their own or a parent class It appears likely that the compiler will refuse to compile. In the following code, if the annotation Sub class "public static int A = 4" , and interfaces exist parent field A, then the compiler will prompt "The field Sub.A is ambiguous", methods ambiguity is the compiler can not determine which method is used in the code, and refuse to compile.

public class FieldResolution {
	
	interface Interface0{
		int A = 0;
	}
	
	interface Interface1 extends Interface0{
		int A = 1;
	}
	
	interface Interface2{
		int A = 2;
	}
	
	static class Parent implements Interface1{
		public static int A = 3;
	}
	
	static class Sub extends Parent implements Interface2{
		public static int A = 4;
	}
	
	public static void main(String[] arg){
		System.out.println(Sub.A);
	}
}

Personal understanding:
Fields resolved first of all to resolve the class of this field is located. For example, the above code will need to resolve Sub class when calling Sub.A, to ensure that Sub class has a direct reference to the virtual machine (actually a class of Sub parsing class, the first point to say). If there is no problem, you can think that this class already in memory, the (assumed to be C). Then virtual machine in the class C inside look to see if there is no such field, (find and follow the simple name field descriptor). If any direct return. If the interface is implemented in C, you need to find all the parent interface inside. If C has a parent class, but also to find in the parent class. I did not find the words to throw an exception. If we succeed, the authority must also be verified.
Sub If the above code in the class "public static int A = 4" commented, you can execute the code written in the main System.out.println (Parent.A); or System.out.println (Interface1.A ); or System.out.println (Interface2.A); this demonstrates that during the parsing of the fields, and the parent class implementation of the interface is also resolved.

Third, the class method to resolve
the first step class analytical method and analytical field, as also need to parse out the class or interface types of precautionary class_index symbol key index table belongs reference method, if successfully resolved, we still use C this class represents the next subsequent virtual machine will search class method the following steps.

  1. Constant type defined class methods and interface method reference symbols are separated, if it is found in the class method table index C is class_index interfaces, it is thrown directly java.lang.IncompatibleClassChangeError exception;
  2. If by the first step, to find out whether there are simple name and descriptor of the target matching the class C, if this method returns a reference to the search ends;
  3. Otherwise, in the list of interfaces and class C implementation of their parent interface recursive method to find out whether there is a simple name and descriptor of the target to match, if it returns a reference to this method, find the end;
  4. Otherwise, the interface list of the class C and achieve their parent interface recursive method to find out whether there is a simple name and descriptor of the target to match, if the matching method exists to prove that C is an abstract class, then the search ends, an exception is thrown java.lang.AbstractMethodError
  5. Otherwise, declaring method lookup fails, throw java.lang.NoSuchMethodError.

Finally, if the process is successfully returned to find a direct reference, this method will verify permissions, if it is found not to have access to this method, will throw java.lang, IllegalAccessError.

Personal understanding: class analytical methods and analytical fields, like, first class analytical method where the (C represented by this class). C can only be a class, not an interface, and if so error. Like other analytical field.

Fourth, the interface method resolution
interface methods also need to parse out the class or interface symbol method class_index entry interface method table index belongs references, if successfully resolved, this still represents an interface written in C, followed by virtual machine will be as follows interface method step subsequent search.

  1. And class methods to resolve different, if it is found in the interface method table class_index entry in the index C is a class rather than an interface, it is a direct throw java.lang.IncompatibleClassChangeError;
  2. Otherwise, look for the interface in C Is there a simple method name and descriptor of the target to match, if there is a direct reference to the return of this method, find the end;
  3. Otherwise, the parent interface Interface C in a recursive lookup until java.lang.Object class (Look will include the Object class) to see if there are ways simple name and descriptor of the target to match, if it returns this direct reference methods, to find the end;
  4. Otherwise, declaring method lookup fails, throw java.lang.NoSuchMethodError.

Since all methods in an interface are public by default, so the problem of access does not exist, a symbol of the interface method does not resolve throw java.lang, IllegalAccessError.

Personal understanding: C only is the interface, can not be invoked in different classes, class methods and interface methods.

Guess you like

Origin blog.csdn.net/huqianlei/article/details/90740165