In-depth exploration of Java class loaders

Source: Internet
Author: User

In-depth exploration of Java class loaders

 

What Is A. class file?

The full name of a class file is called a Java class file, which makes Java more suitable for the network in terms of platform independence and Network Mobility. In terms of platform independence, it provides binary services independent of the underlying host platform for Java programs. The class file path breaks the tradition of C, C ++, and other languages. programs written in these traditional languages are usually compiled first, then it is connected to a separate binary file dedicated to supporting specific hardware platforms and operating systems. Generally, binary executable files on one platform cannot work on other platforms. Java class files are binary files that can run on any hardware platform and operating system that supports Java virtual machines. This is also the real reason why Java claims "one-time compilation and running everywhere", because the Java files on various systems are compiled into. class files, and then loaded and run through virtual machines.

What is a class loader?

A Class Loader is a class used to load class files. Java source code is compiled into class files through the javac compiler. Then the JVM executes the bytecode in the class file to execute the program. The class loader is responsible for loading class files from the file system, network, or other sources. There are three default class loaders: Bootstrap class loader, Extension class loader, and System class loader (or Application Class Loader ). Each type of loader has a set where to load the class.

What happened to generate an object instance?

To generate an instance, the program will use the compiler to generate bytecode files for the corresponding class java files, and then wait until such static variables or methods are called or instances are generated, the virtual machine automatically finds the bytecode file in the corresponding directory, loads it to the virtual machine, and generates the corresponding instance object. Each bytecode file is loaded only once. The process is as follows:

 

 

Class Loading Method

Java provides two methods to achieve dynamic rows. One is implicit and the other is explicit. The underlying mechanisms used in these two methods are identical, with only different program codes. Implicitly, when the new Java keyword is used, the Class Loader loads the required classes as needed. There are two explicit methods: one is to borrow java. lang. the forName () method in the Class, the other is to borrow java. lang. the loadClass () method in ClassLoader.

Tree Structure of the class loader and the directory for loading files

The class loaders in Java can be roughly divided into two types: one is provided by the system, and the other is compiled by Java application developers. The system provides the following class loaders:

(1) Bootstrap ClassLoader (Bootstrap Class Loader): it is used to load the core library of Java. It is implemented using native code and does not inherit from java. lang. ClassLoader. Will be stored in In the lib directory, or in the path specified by the-Xbootclasspath parameter, and recognized by virtual machines (only by file name, such as rt. libraries with invalid jar names are not loaded even in the lib directory.) the class libraries are loaded into the VM memory. The Class Loader cannot be directly referenced by Java programs.

(2) Extension ClassLoader: it is used to load Java Extension libraries. The Java virtual machine provides an extension library directory. This class loader searches for and loads Java classes in this directory. Set In the libext directory or by all class libraries in the path specified by the java. ext. dirs system variable. Developers can directly use the extension class loader.

(3) Application ClassLoader or System Classloader: responsible for loading the class library specified on the user ClassPath, which can be directly used by developers. It loads the Java class according to the CLASSPATH of the Java application. Generally, Java application classes are loaded by them. You can obtain it through ClassLoader. getSystemClassLoader.

There are two ways to get the organizational structure of the Class Loader:

 

Package com. lin; public class ClassLoadTest1 {public static void main (String [] args) {ClassLoader loader = ClassLoadTest1.class. getClassLoader (); ClassLoader loader1 = ClassLoader. getSystemClassLoader (); // get the loader from child to parent while (loader! = Null) {System. out. println (loader. toString (); loader = loader. getParent () ;}while (loader1! = Null) {System. out. println (loader1.toString (); loader1 = loader1.getParent ();}}}

 

Output result:

 



 

You can see that both methods first obtain the Application ClassLoader and then the Extension ClassLoader.

Table 1. methods related to the loading class in ClassLoader
Method description
GetParent () returns the parent class loader of the class loader.
LoadClass (String name) loads the Class named name and returns an instance of the java. lang. Class.
FindClass (String name) finds the Class named name and returns an instance of the java. lang. Class.
FindLoadedClass (String name) finds the loaded Class named name, and returns an instance of the java. lang. Class.
DefineClass (String name, byte [] B, int off, int len) converts the content in byte array B to a Java Class and returns an instance of the java. lang. Class. This method is declared as final.
ResolveClass (Class C) link to the specified Java class.
In addition to the class loaders provided by the system, developers can inherit the java. lang. ClassLoader class to implement their own class loaders to meet some special requirements. In addition to the bootstrap loader, all classloaders have a parent loader. The getParent () method given in Table 1 can be used to obtain the result. For the class loader provided by the system, the parent class loader of the system class loader is the extension class loader, and the parent class loader of the extension class loader is the bootstrap class loader; for a class loader compiled by developers, its parent class loader is a class loader that loads the Java class of this class loader. Because the Class Loader Java class, like other Java classes, also needs to be loaded by the class loader. Generally, the parent class loader of the Class Loader compiled by developers is the system class loader. The class loader is organized in this way to form a tree structure. The root node of the tree is the bootstrap loader. A typical Class Loader tree structure is provided. The arrow points to the parent class loader.

 

The specific process of each load:

Working Process of the Class Loader

The class loader is used to find the class bytecode file and construct the object components represented by the class in JVM. In Java, to load a class into JVM, follow these steps:
(1) load: Find and import Class files;
(2) Link: Merge binary data of the class into JRE;
(A) Check: Check the correctness of the data loaded into the Class file;
(B) Preparation: allocate storage space to static variables of the class;
(C) parsing: converting a symbolic reference into a direct reference;

(3) initialization: Initialize static variables and static code blocks of the class.

Working principle of the Class Loader


(1) delegation Mechanism
When a class is loaded and initialized, the class is loaded only when it needs to be loaded. Suppose you have an application that requires a class called Abc. class: first, the Application class Loader delegates the request for loading this class to its parent class loader Extension class loader, and then delegates it to the Bootstrap class loader. The Bootstrap class loader will first look at rt. jar does not have this class. Because this class does not exist, this request is returned to the Extension class loader. It will check whether this class exists in the jre/lib/ext directory, if this class is found by the Extension class loader, it will be loaded, and the Application class loader will not load this class. If this class is not found by the Extension class loader, then, the Application classloader looks for it from classpath. Remember that classpath defines the directory for loading class files, while PATH defines the execution paths of executable programs such as javac and java.

Working Process: If a Class Loader receives a class loading request, it first delegates the request to its parent class loader for completion. This is true for class loaders at each level, therefore, all the load requests should be sent to the top-level startup class loader, only when the parent loader reports that it cannot complete the load request (it does not find the desired class in the search range) Will the child loader attempt to load it by itself.

 



 

Benefit: a java class has a level of priority along with its class loader. For example, java. lang. object, which is stored in rt. in jar, no matter which class loader needs to load this class, it will eventually Delegate to the startup Class Loader for loading, therefore, the Object class is the same class in the loader environment of various types of programs. On the contrary, if you write a file named java. lang. object Class and put it in the program's Classpath. Then, there will be multiple different Object classes in the system, and the most basic behavior in the java type system cannot be guaranteed, applications can also become messy.

First, you need to explain how the Java Virtual Machine judges that the two Java classes are the same. The Java virtual machine not only needs to check whether the full name of the class is the same, but also whether the class loader to load this class is the same. Only when the two are the same can the two classes be considered the same. Even for the same byte code, the classes obtained after being loaded by different class loaders are also different. For example, a Java class com. example. Sample is compiled and the byte code file Sample. class is generated. Two different class loaders, ClassLoaderA and ClassLoaderB, read the Sample. Class file and define two java. lang. class instances to represent the Class. The two instances are different. For Java virtual machines, they are different classes. Attempting to assign values to the objects of these two classes will throw a runtime exception ClassCastException. The following is an example.

 

package com.lin;public class Sample {private Sample instance;     public void setSample(Object instance) {         this.instance = (Sample) instance;     }     public void say(){    System.out.println(Hello LinBingwen);    }}

Then use:

 

 

Package com. lin; import java.net. *; import java. lang. reflect. *; public class ClassLoadTest4 {public static void main (String [] args) throws ClassNotFoundException, expiration, expiration, NoSuchMethodException, InstantiationException, InvocationTargetException {ClassLoader pClassLoader = ClassLoader. getSystemClassLoader (); // Use System ClassLoader as the parent class loader URL [] baseUrls = {new URL (file:/E:/workspace/Eclipse/ClassLoadTest )}; // search for the class library directory final String binaryName = com. lin. sample; // binary name of the class to be loaded ClassLoader userClassLoader1 = new URLClassLoader (baseUrls, pClassLoader); ClassLoader userClassLoader2 = new URLClassLoader (baseUrls, pClassLoader ); class clazz1 = Statement (binaryName); Class clazz2 = Statement (binaryName); Object instance1 = clazz1.newInstance (); Object instance2 = clazz2.newInstance (); // call the say method clazz1.getMethod (say ). invoke (instance1); clazz2.getMethod (say ). invoke (instance2); // binary name of the output class System. out. println (clazz1.toString (); System. out. println (clazz2.toString (); // compare whether the addresses of the two classes are the same System. out. println (clazz1 = clazz2); // compare whether the two classes are the same or whether they are inherited from the System. out. println (clazz1.isAssignableFrom (clazz2); // check whether type conversion is successful boolean ret = true; try {Method setSampleMethod = clazz1.getMethod (setSample, java. lang. object. class); setSampleMethod. invoke (instance1, instance2);} catch (Exception e) {e. printStackTrace ();} System. out. println (ret );}}
Output result:

 

 

Because both are from ClassLoader. getSystemClassLoader (); // Use System ClassLoader as the parent class loader, so the two loaders are actually the same.

(2) Visibility Mechanism
Based on the visibility mechanism, the subclass loader can see the classes loaded by the parent class loader, but not vice versa. In the following example. the class has been loaded by the Application class Loader. If you want to use the Extension class loader to load this class, java will be thrown. lang. classNotFoundException exception.

 

Package com. lin; import java. util. logging. level; import java. util. logging. logger; public class ClassLoadTest2 {public static void main (String [] args) {try {// print the current class loader System. out. println (ClassLoadTest2.getClass (). getClassLoader (): + ClassLoadTest2.class. getClassLoader (); // use the extension Class loader to load the Class loaded by the subclass loader again. forName (com. lin. classLoadTest1, true, ClassLoadTest2.class. getClassLoader (). getParent ();} catch (ClassNotFoundException ex) {Logger. getLogger (ClassLoadTest2.class. getName ()). log (Level. SEVERE, null, ex );}}}

 

(3) Singularity Mechanism
According to this mechanism, the class loaded by the parent loader cannot be loaded by the quilt loader for the second time. It is possible to rewrite a class loader that violates the delegate and singularity mechanisms, but this is not desirable. You should strictly abide by these three mechanisms when writing your own 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.