Java ClassLoader in-depth exploration

Source: Internet
Author: User

Lin Bingwen Evankakaoriginal works. Reprint please indicate the sourceHttp://blog.csdn.net/evankaka

what is the. class file?

The full name of the class file is called the Java class file, which makes Java more suitable for the network in terms of platform independence and network mobility. Its mission in terms of platform independence is to provide Java programs with a binary form of service that is independent of the underlying host platform. The class file path breaks the tradition of languages such as C or C + +, and programs written in these traditional languages are usually compiled first and then connected to a separate binary file that specifically supports specific hardware platforms and operating systems. Typically, binary executables on one platform do not work on other platforms. The Java class file is a binary file that can run on any hardware platform and operating system that supports Java virtual machines. And that's the real reason that Java claims to be "compiled, run everywhere," because Java files on each system are compiled into a. class file and then loaded by a virtual machine to run.

what is a class loader?

The class loader is a class that is used to load class files. The Java source code is compiled into a class file by the Javac compiler. The JVM then executes the code in the class file to execute the program. The class loader is responsible for loading the file system, network, or other source class files. There are three default class loaders: The bootstrap class loader, the extension class loader, and the System class loader (or called the application ClassLoader). Each type of loader has a set of where to load the class.

generate an object instance what happened?

Generate an instance, the program will be the corresponding class of Java files using the compiler to generate bytecode files, and so on when this class is called static variables or methods or generate instances, the virtual machine automatically go to the appropriate directory to find the bytecode file, and load into the virtual machine, and then generate the corresponding instance object. Each bytecode file will only be loaded once. The process is as follows:



how the class loads

Java provides two ways to achieve dynamic rows, one is implicit and the other is explicit. The underlying mechanism of the two approaches is exactly the same, with only the difference in program code. Implicitly, when you use the new Java keyword, the ClassLoader loads the required classes on demand. Explicit is divided into two methods: one is to borrow the forname () method in Java.lang.Class, and the other is to borrow the LoadClass () method in Java.lang.ClassLoader.

the tree-like structure of the ClassLoader and the loading file directory

The ClassLoader in Java can be broadly divided into two categories, one for the system, the other for Java application developers. There are three main types of ClassLoader available in the system:

(1) Bootstrap ClassLoader (Boot class loader): It is used to load Java core library, is implemented with native code, does not inherit from Java.lang.ClassLoader. will be stored in the <java_home>\lib directory, or in the path specified by the-xbootclasspath parameter, and is recognized by the virtual machine (identified by file name only, such as Rt.jar Class libraries with names that do not conform are loaded into virtual machine memory even if they are placed in the Lib directory. Startup ClassLoader cannot be referenced directly by Java programs

(2) Extension ClassLoader (Extension class loader): It is used to load the Java extension library. The implementation of the Java virtual machine provides an extension library directory. The ClassLoader finds and loads the Java class in this directory. Load all class libraries in the <java_home>\lib\ext directory, or in the path specified by the Java.ext.dirs system variable. Developers can use the extension class loader directly.

(3) Application Classloader or called System Classloader (System ClassLoader): Responsible for loading the class library specified on the user classpath (ClassPath), which can be used directly by the developer. It loads the Java class according to the Classpath (CLASSPATH) of the Java application. In general, Java-applied classes are loaded by it. It can be obtained by Classloader.getsystemclassloader ().

There are two ways to get the class loader's organizational structure:

Package Com.lin;public class ClassLoadTest1 {public static void main (string[] args) {ClassLoader loader = ClassLoadTest1. Class.getclassloader ();  ClassLoader loader1 = Classloader.getsystemclassloader (); From child to parent get loader        while (loader! = null) {             System.out.println (loader.tostring ());             Loader = Loader.getparent ();         }         while (loader1! = null) {             System.out.println (loader1.tostring ());             Loader1 = Loader1.getparent ();         } }}

Output Result:



As can be seen, both methods are first obtained application ClassLoader, and then obtained extension ClassLoader.

Table 1. Methods related to load classes in ClassLoader
Method description
GetParent () returns the class loader's parent class loader.
LoadClass (String name) loads the class named name, and the returned result is an instance of the Java.lang.Class class.
Findclass (String name) looks for the class with name, and the result is an instance of the Java.lang.Class class.
Findloadedclass (String name) looks for a class that has already been loaded named name, and the result is an instance of the Java.lang.Class class.
DefineClass (String name, byte[] B, int off, int len) converts the contents of byte array B into a Java class, and the result returned is an instance of the Java.lang.Class class. This method is declared final.
Resolveclass (class<?> c) links the specified Java class.
In addition to the system-provided classloader, developers can implement their own classloader by inheriting the Java.lang.ClassLoader class to meet some special requirements. All Class loaders have a parent class loader, in addition to the boot class loader. It can be obtained by the GetParent () method given in table 1. For the system-provided ClassLoader, the parent classloader of the system ClassLoader is the extension class loader, and the parent classloader of the extension ClassLoader is the boot class loader, and for a developer-written class loader, its parent classloader is the ClassLoader that loads the class loader Java class. Because the ClassLoader Java class is like any other Java class, it is also loaded by the ClassLoader. In general, the developer-written class loader's parent ClassLoader is the System class loader. The ClassLoader is organized in such a way that it forms a tree-like structure. The root node of the tree is the boot class loader. A typical class loader tree structure is given, with arrows pointing to the parent ClassLoader.



Each time the specific process is loaded:

class loader work process

A class loader is a byte-code file that looks for a class and constructs an object component that the class represents within the JVM. In Java, the class loader loads a class into the JVM, taking the following steps:
(1) Loading: Find and import class files;
(2) Link: Merges the binary data of the class into the JRE;
(a) Verification: check the correctness of loading class file data;
(b) Preparation: Allocating storage space to static variables of the class;
(c) Parsing: Transferring symbolic references to direct references;

(3) Initialize: Static variable for class, static code block to initialize operation

how the class loader works


(1) Commission mechanism
When a class is loaded and initialized, the class is loaded only when it needs to be loaded. Assuming that you have an application that requires a class called Abc.class, the request to load the class first is delegated by the Application class loader to its parent ClassLoader extension class loader, and then to the Bootstrap class loader. The Bootstrap class loader will first see if there is no such class in Rt.jar, because there is no such class, so this request is returned by the Extension class loader, which will look at the Jre/lib/ext directory if there is no such class, if this class was found by the extension class loader , then it will be loaded, and the application class loader will not load this class, and if the class is not found by the extension ClassLoader, then the application class loader is looking for it from classpath. Remember that classpath defines the load directory for class files, and path is the execution path that defines executable programs such as Javac,java.

Working process: If a class loader receives a request for a class load, it first delegates the request to his parent class loader to complete, so that all the load requests should be routed to the start class loader at the top level. The child loader tries to load itself only when the parent loader has feedback that it cannot complete the load request (it does not find the desired class in the search scope).



Benefit: The Java class has a hierarchical relationship with precedence as its classloader. For example, the class Java.lang.Object, which is stored in Rt.jar, regardless of which class loader is loading the class, will eventually be delegated to the startup ClassLoader for loading, so the Object class is the same class in the various class loader environments of the program. Conversely, if the user writes a class named Java.lang.Object and puts it in the program's classpath, there will be several different object classes in the system, and the most basic behavior in the Java type System is not guaranteed and the application becomes chaotic.

The first step is to explain how a Java virtual machine determines that two Java classes are the same. The Java virtual machine depends not only on whether the full name of the class is the same, but also on whether the class loader loading this class is the same. The two classes are the same only if they are the same. Even the same byte code is different from the classes that are obtained after the loading of different classloader. A Java class com.example.Sample, for example, generates a byte code file sample.class after compiling. Two different ClassLoader Classloadera and Classloaderb read the Sample.class file separately and define two instances of the Java.lang.Class class to represent the class. These two instances are not the same. For Java virtual machines, they are different classes. Attempting to assign values to objects of these two classes throws a run-time exception classcastexception. The following is an example of how to specify.

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 it is used:

Package Com.lin;import Java.net.*;import java.lang.reflect.*;p ublic class classloadtest4{public static void main ( String[] args) throws ClassNotFoundException, Malformedurlexception, Illegalaccessexception, Nosuchmethodexception, Instantiationexception, invocationtargetexception{ClassLoader pclassloader = Classloader.getsystemclassloader ();// Use System ClassLoader as the parent ClassLoader url[] Baseurls = {new URL ("File:/e:/workspace/eclipse/classloadtest")}; Search catalog for Class Library final String binaryname = "Com.lin.Sample";    The binary name of the class that needs to be loaded ClassLoader UserClassLoader1 = new URLClassLoader (Baseurls, Pclassloader);    ClassLoader userClassLoader2 = new URLClassLoader (Baseurls, Pclassloader);    Class clazz1 = Userclassloader1.loadclass (binaryname);    Class clazz2 = Userclassloader2.loadclass (binaryname);    Object Instance1 = Clazz1.newinstance ();    Object Instance2 = Clazz2.newinstance ();    Call the Say method Clazz1.getmethod ("say"). Invoke (Instance1);    Clazz2.getmethod ("Say"). Invoke (INSTANCE2); LoseThe binary name of the Out class System.out.println (clazz1.tostring ());    System.out.println (Clazz2.tostring ());    Compare the addresses of two classes with the same System.out.println (clazz1 = = CLAZZ2);    Compares whether two classes are the same or is an inheritance relationship System.out.println (Clazz1.isassignablefrom (CLAZZ2));    View whether the type conversion succeeded 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 they are all from classloader.getsystemclassloader (); With System ClassLoader as the parent ClassLoader, two loaders are actually the same.

(2) Mechanism of visibility
Depending on the visibility mechanism, the subclass loader can see the classes loaded by the parent ClassLoader, and vice versa. So in the example below, when Abc.class has been loaded by the application class loader, and if you want to load the class with the extension ClassLoader, you will throw a java.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 {                      //prints the current class loader            System.out.println ("Classloadtest2.getclass (). getClassLoader (): "                                 + ClassLoadTest2.class.getClassLoader ());            Use the extension classloader to load the class.forname loaded by the child ClassLoader            ("Com.lin.ClassLoadTest1", True                            ,  ClassLoadTest2.class.getClassLoader (). GetParent ());        } catch (ClassNotFoundException ex) {            Logger.getlogger (ClassLoadTest2.class.getName ()). log (Level.severe, NULL, EX );        }}}

(3) The mechanism of singleness
According to this mechanism, the class that the parent loader has loaded cannot be loaded by the quilt loader a second time. Although it is possible to override a classloader that violates delegates and singleness mechanisms, it is not advisable to do so. You should strictly abide by these three mechanisms when you write your own classloader.


Reference article:

1, https://www.ibm.com/developerworks/cn/java/j-lo-classloader/

2, http://www.cnblogs.com/ITtangtang/p/3978102.html

3, http://www.cnblogs.com/rason2008/archive/2012/01/01/2309718.html

4, http://www.importnew.com/6581.html


Copyright NOTICE: This article for Bo Master Lin Bingwen Evankaka original article, reproduced please indicate the source Http://blog.csdn.net/evankaka

Java ClassLoader in-depth exploration

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.