Loading, linking, and initializing of Java classes

Source: Internet
Author: User
Tags apache tomcat websphere application server

first, the Java class loading mechanism review and summary:

We know that a Java class wants to run, it must be loaded into memory by the JVM to run, and the purpose of the load is to Java convert the byte code into JVM the object of the java.lang.Class class in. This allows Java to perform a series of operations on the object, and the loading process has two more important features: hierarchical organizational structure and proxy mode. Hierarchical organizational structure refers to each classloader has a parent class loader, which can be obtained through the GetParent () method. The ClassLoader is organized in such a way that fathers-descendants form a tree-like hierarchy. The proxy mode refers to a class loader that can either do its own work on the definition of a Java class or delegate to other ClassLoader. Because of the presence of proxy mode, the class loader that initiates the loading of a class and the class loader that ultimately defines the class may not be one. ClassLoader's load class process mainly uses the LoadClass method, which encapsulates the medium loading mechanism: Parental delegation mode.

In general, the parent priority strategy is good enough. In some cases, it may be necessary to take the opposite strategy, which is to try to load it yourself and then delegate to the parent class loader when it is not found. This approach is common in Java Web containers and is Servlet a recommended practice for the specification. For example, Apache Tomcat for each Web application to provide a separate class loader, the use of their own priority to load the policy. IBM WebSphere Application Serverallows the Web app to select the policy used by the ClassLoader.
An important use of the ClassLoader is to JVM create an isolation space for Java classes of the same name in. In JVM , determine whether two classes are the same, not only based on the binary name of the class, but also the class loader according to the two class definition. The two classes are identical only if they are exactly the same. Therefore, even if the same Java byte code is defined by two different classloader, the resulting Java classes are different. If an attempt is made to assign a value to an object of two classes, it is thrown java.lang.ClassCastException . This feature creates conditions for classes of the same name to Java exist in the JVM CCP. In a real-world application, different versions of a class of the same name may be required to Java JVM exist concurrently. This needs to be met through the ClassLoader. This technology has been widely used in the OSGi

The loading process for Java classes:

1. The binary data stream of the corresponding class is generated by the full name of the class. (if the corresponding class file is not found, an error is thrown only when the class is actually used.) )
2. Analyze and convert these binary data streams to a method area (the JVM's schema: Method area, heap, stack, local method stack, PC register) specific data structures (these data structures are implementation-related, different JVMs have different implementations). Some tests are handled here, such as the validation of the magic number of the class file, checking if the file is too long or too short, and determining if there is a parent class (except for the Obecjt Class).
3. Create a Java.lang.Class instance of the corresponding class (note that with the corresponding class instance, it does not mean that the class has completed the load chain link!) )。

links to Java classes

A link to a Java class refers to the process of merging the Java class's binary code into the running state of the JVM. Before linking, this class must be loaded successfully.
The process of linking is much more complex than the loading process, which is an important step in implementing Java's dynamic nature! Divided into three parts: verification (detection), preparation (preparation) and resolution (parsing)

1. verification (detection):
Validation is used to ensure that the binary representation of the Java class is structurally correct. If there is an error in the validation process, an error is thrown java.lang.VerifyError .

Linking's resolve will replace the symbolic references of member methods, member variables, classes, and interfaces in the class with direct references, and before that, it is necessary to detect the correctness of the referenced type and whether the Access property is correct (that is, public, private) such as checking the final Class is not inherited, check the correctness of static variables, and so on.
Validation is used to ensure that the binary representation of the Java class is structurally correct. If there is an error in the validation process, an error is thrown java.lang.VerifyError .

2. preparation (Preparation):

The preparation process is to create a Java static domain in the class and set the values of those fields to the default values. The preparation process does not execute code. A Java class contains a formal reference to another class or interface, including its parent class, the implemented interface, the form parameters of the method, and the class that returns the value Java .

Allocates space for member variables of the class. Although there are initial values, they are not initialized at this time (because no Java code is executed here). Specific as follows:
All primitive types have values of 0. such as float:0f, int:0, boolean:0 (note that the boolean underlying implementation mostly uses int), and the reference type is null. It is important to note that the JVM may allocate space for some data structures that will help the program run more efficiently during this time.

3. resolution (parsing):

The process of parsing is to make sure that the referenced classes are correctly found. The parsing process may cause other Java classes to be loaded.

position the direct reference for the symbol reference of the class, interface, method, member variable (if the symbol reference first looks for the symbol in the constant pool, and then the type to be first, Will undoubtedly take more time) to complete the layout of the memory structure.
This step is optional. This can be done when the symbol reference is first used, the so-called delay resolution (late resolution). However, for the user, this step is always deferred parsing, even if the runtime will execute early resolution, but the program will not show the first error when the error is thrown, but the corresponding class will be the first time the active use of the error thrown!

look at the following code:

 class   Linktest { public  static  void   main (string[] args) {T             obelinked tobelinked  = null   "Test link.")      ); }}

Class LinkTest refers to a class ToBeLinked , but does not actually use it, but declares a variable, does not create an instance of the class, or accesses a static domain in it. If the compiled ToBeLinked Java byte code is removed and then run LinkTest , the program does not throw an error. This is because the ToBeLinked class is not actually used. The link policy makes the ToBeLinked class not be loaded, so ToBeLinked the Java bytecode code that is not found is actually nonexistent. If you change the code ToBeLinked toBeLinked = new ToBeLinked(); and then run it the same way, you will throw an exception. Because this ToBeLinked class is actually used at this time, this class will need to be loaded.

third, the initialization of Java class

When developing Java, the most contact is the initialization of the object. In fact, classes are also initialized. The initialization mechanism of the class is much simpler than the initialization of the object.
The initialization of a class is also deferred until the first time the class is actively used (active use), the JVM initializes the class.
When a Java class is first actually used, the JVM performs the initialization of that class. The primary operation of the initialization process is to execute static blocks of code and initialize the static domain. Before a class is initialized, its immediate parent class also needs to be initialized. However, the initialization of an interface does not cause the initialization of its parent interface. At initialization time, static blocks of code and initialization of the static domain are executed sequentially from top to bottom in the source code.

 Public classStatictest { Public Static intX = 10;  Public Static voidMain (string[] args) {System.out.println (Y);//Output   }      Static{X= 30; }      Public Static intY = X * 2;}

In the code above, the initialization of the static domain and execution of the static code block are executed from top to bottom at initialization time. So the value of the variable x is first initialized to 10 and then to 30, while the value of the variable y is initialized to 60.
The initialization of a class is divided into two steps:

1. If the base class is not initialized, initialize the base class.
2. There is a class constructor, then the class constructor is executed.

The class constructor is done by the Java compiler. It extracts the initialization of the class member variable and the code of the static interval, and puts it into a <clinit> method. This method cannot be accessed by a generic method (note that the static final member variable is not initialized here, it is generally generated by the compiler constant value). At the same time, the <clinit> call base class is not displayed because the initialization of the <clinit> base class has already been performed in 1. The initialization process is guaranteed to be thread-safe by the JVM:

Initialization of Java classes and interfaces occurs only at a specific time, including:

New= Ten accesses the static domain declared in the Java class or interface, and the domain is not a constant variable.    An Assert statement is executed in the top-level Java class, such as int value = Myclass.value. 

The Java Reflection API may also cause initialization of classes and interfaces. It is important to note that when accessing a Java static domain in a class or interface, only the class or interface that actually declares the domain is initialized. Consider the following code:

classB {Static intValue = 100; Static{System.out.println ("Class B is initialized.");//Output   }}classAextendsB {Static{System.out.println ("Class A is initialized.");//does not output   }} Public classInittest { Public Static voidMain (string[] args) {System.out.println (a.value);//Output   }}

In the preceding code, the class refers to the InitTest A.value static domain declared in class B value . Because value it is declared in a class B , only the class is B initialized, and Class A is not initialized.

Loading, linking, and initializing of Java classes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.