Java in-depth adventure (2) -- loading, linking, and initializing Java classes

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

Original article: http://www.infoq.com/cn/articles/cf-Java-class-loader

In the previous article, we introduced Java bytes.CodeJava class loader is used to load modified byte code and execute it on JVM. Next, I will discuss the loading, linking, and initialization of Java classes. Java byte code is represented in byte arrays (byte []), while Java classes in JVM are represented in Java. Lang. Class classes.
. To use a Java class from byte code to JVM, you must load, link, and initialize the class. In the three steps, developers can directly see the addition of Java classes.
By using the Java class loader (Class
Loader) can dynamically load a Java class at runtime, And the link and initialization are the actions that will occur before the Java class is used. This article will introduce in detail the loading, linking, and
The initialization process.

Java class loading

Java classes are loaded by the class loader. Generally, classloaders are divided into Bootstrap and user-defined classloaders ). The difference between the two is that the start class loader is implemented by the native JVM code, and the user-defined class loader inherits from the java. Lang. classloader class in Java. In the user-defined class loaders, JVM generally provides some basic implementations. ApplicationProgramDevelopers can also compile their own class loaders as needed. The most common JVM is the system loader, which is used to start loading Java applications. You can use the getsystemclassloader () method of Java. Lang. classloader to obtain the object of the class loader.

The final function required by the class loader is to define a Java class, that is, to convert the java byte code into the java. Lang. Class class object in JVM. However
It is not that simple. Java class loaders have two important features: hierarchical structure and proxy mode. The hierarchy structure means that each class loader has a parent class loader, which is passed through getparent ()
Method. The Class Loader organizes the Parent-Child together to form a tree hierarchy. The proxy Mode means that a class loader can define Java classes by itself or
It is done by proxy to other class loaders. Because of the existence of the proxy mode, the class loader that starts the loading process of a class and the class loader that finally defines this class may not be one. The former is called the initial class loader,
The latter is called the definition class loader. The association between the two is that a Java class definition class loader is the initial class loader of other Java classes imported by this class. For example, Class A imports the class through import.
B. The class a loader is responsible for starting the loading process of Class B.

Before you try to load a Java class, the Class Loader first proxies to its parent class loader. When the parent class loader cannot be found, it will try to load it by itself. This logic is encapsulated in the loadclass () method of the Java. Lang. classloader class. Generally, the parent class priority policy is good enough. In some cases, you may need to adopt the opposite policy, that is, first try to load by yourself, and then proxy to the parent class loader when it cannot be found. This method is common in Java Web containers and recommended in servlet specifications. For example, Apache Tomcat provides an independent class loader for each web application and uses its own load-first policy. IBM WebSphere Application Server allows web applications to select the policies used by the class loader.

An important purpose of the Class Loader is to create an isolation space for Java classes with the same name in JVM. In JVM, determine whether the two classes are the same, not only according to the binary name of the class, but also according to the definition of the Class Loader of the two classes. Only when the two are identical can the two classes be considered the same. Therefore, even if the same JAVA byte code is defined by two different class loaders, the Java classes are different. If you try to assign values between two classes, a java. Lang. classcastexception will be thrown. This feature creates conditions for coexistence of Java classes with the same name in JVM. In practice, different versions of Java classes with the same name may be required to exist simultaneously in JVM. The class loader can meet this requirement. This technology is widely used in osgi.

Java class Link

The Java class link refers to the process of merging the binary code of the Java class into the running state of the JVM. The class must be loaded successfully before the link is linked. Class links include verification, preparation, parsing, and other steps. Verification is used to ensure that the binary representation of the Java class is fully correct in structure. If an error occurs during the verification process, the Java. Lang. verifyerror error will be thrown.
Error. The preparation process is to create static fields in the Java class and set the values of these fields to the default values. The preparation process does not execute the code. A Java class contains references to other classes or interfaces.
Including its parent class, implemented interface, method form parameters, and returned value Java class. The parsing process is to ensure that these referenced classes can be found correctly. The parsing process may cause other
The Java class is loaded.

Different JVM implementations may choose different resolution policies. One way is to recursively resolve all references in the form of links. The other method may be to direct
It is parsed only when it is actually needed. That is to say, if a Java class is referenced but not actually used, the class may not be parsed. Consider the following code:

Public class linktest {public static void main (string [] ARGs) {tobelinked = NULL; system. Out. println ("test link .");}}

The class linktest references the class tobelinked, but does not actually use it. It only declares a variable and does not create an instance of the class or access the static domain. In
Oracle JDK
6. If you delete the compiled tobelinked JAVA byte code and then run linktest, the program will not throw an error. This is because the tobelinked class does not
It is actually used, and the JDK of Oracle
6. The link policy is adopted so that the tobelinked class will not be loaded, so it will not find that the tobelinked Java Byte Code does not actually exist. If you change the code
Tobelinked = new
After tobelinked (); and then run it in the same way, an exception will be thrown. This is because the tobelinked class is actually used, and the class needs to be loaded.

 

Java class initialization

When a Java class is used for the first time, JVM initializes the class. The main operations during initialization are to execute static code blocks and initialize static fields. When a class is initialized
Its direct parent class also needs to be initialized. However, initialization of an interface does not cause initialization of its parent interface. During initializationSource codeExecute static code blocks sequentially from top to bottom
And initialize static fields. Consider the following code:

Public class statictest {public static int x = 10; public static void main (string [] ARGs) {system. out. println (y); // output 60} static {x = 30;} public static int y = x * 2 ;}

In the above Code, static domain initialization and static code block execution are performed from top to bottom during initialization. Therefore, the value of variable X is first initialized to 10, and then assigned to 30. The value of variable Y is initialized to 60.

 

Java class and interface initialization only occurs at a specific time, including:

    • Create a Java class instance. For example

      Myclass OBJ = new myclass ()
    • Call a static method in a Java class. For example
      Myclass. sayhello ()
    • Assign values to static fields declared in Java classes or interfaces. For example
      Myclass. value = 10
    • Access static fields declared in Java classes or interfaces, and the field is not a constant variable. For example
      Int value = myclass. Value
    • Execute the assert statement in the top-level Java class.

Using Java reflection APIs may also cause class and interface initialization. It should be noted that when accessing a static domain in a Java class or interface, only classes or interfaces that actually declare this domain will be initialized. Consider the following code:

Class B {static int value = 100; static {system. out. println ("Class B is initialized. "); // output} Class A extends B {static {system. out. println ("Class A is initialized. "); // No output} public class inittest {public static void main (string [] ARGs) {system. out. println (. value); // output 100 }}

In the above Code, the class inittest references the static Domain value declared in Class B through a. value. Because the value is declared in Class B, only Class B is initialized, and Class A is not initialized.

 

Create your own class loader

In
During Java application development, you may need to create your own class loader. Typical scenarios include implementing specific JAVA byte code search methods, encrypting/decrypting byte code, and implementing the Same Name
Java class isolation. Creating your own classloaders is not complicated. You only need to inherit from the java. Lang. classloader class and override the corresponding method.
Many methods are provided in Java. Lang. classloader. The following describes several considerations when creating a Class Loader:

    • Defineclass (): This method is used to complete the conversion from the byte array of JAVA byte code to Java. Lang. Class. This method cannot be overwritten and is generally implemented using native code.
    • Findloadedclass (): This method is used to find the loaded Java class by name. A Class Loader does not repeatedly load classes with the same name.
    • Findclass (): This method is used to search for and load Java classes by name.
    • Loadclass (): This method is used to load the Java class according to the name.
    • Resolveclass (): This method is used to link a Java class.

Comparison
What is confusing is the role of the findclass () method and the loadclass () method. As mentioned above, during the Java class link process, the Java class needs to be parsed
Analysis may cause other Java classes referenced by the current Java class to be loaded. At this time, the JVM calls the loadclass () method of the current class definition class loader to load other
Class. The findclass () method is an extension of the Class Loader created by the application. The application's own class loader should overwrite the findclass () method to add custom class loading logic.
The default implementation of the loadclass () method calls the findclass () method.

As mentioned above, the proxy mode of the Class Loader uses the parent class priority policy by default. The implementation of this policy is encapsulated in the loadclass () method. If you want to modify this policy, you need to override the loadclass () method.

The following code provides common implementation modes for custom class loading:

Public class myclassloader extends classloader {protected class <?> Findclass (string name) throws classnotfoundexception {byte [] B = NULL; // find or generate the byte code of the Java class return defineclass (name, B, 0, B. length );}}
References
    • Java language specification (Third edition)-Chapter 13th: Execution
    • JVM specifications (version 2)-Chapter 5: Loading, linking, and initialization
    • In-depth discussion on Java class loaders

 

 

Related Article

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.