Java class loading mechanism detailed

Source: Internet
Author: User
Tags object object

First, class loader

The class loader (ClassLoader), as the name implies, is something that loads classes. Before we can use a class, the JVM needs to load the class's bytecode file (. class file) from disk, network, or other source into memory, and parse the bytecode to generate the corresponding class object, which is the function of the ClassLoader. We can use the class loader to implement dynamic loading of classes.

Second, the loading mechanism of the class

In Java, a parent delegation mechanism is used to implement class loading. What is the parent delegation mechanism? In Java doc, there is a description:

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader have an associated parent class loader. When requested to find a class or resource, a ClassLoader instance would delegate the search for the class or resource to I TS Parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the "Bootstrap class loader", does not itself has a parent but may SE Rve as the parent of a ClassLoader instance.

From the above description, we can summarize the following four points:  
1, the loading process of the class adopts the delegate mode to implement  
2, each ClassLoader has a parent loader.  
3, the class loader recursively attempts to load with the parent loader before loading the class.  
4. The virtual machine has a built-in boot class loader (Bootstrap classloader) that does not have a parent loader, but can act as the parent loader for other loaders.  
Java provides three types of system ClassLoader. The first is to launch the ClassLoader, implemented by the C + + language, which is part of the JVM that loads the files in the/lib directory, and the ClassLoader loads only files of a particular name, such as Rt.jar, rather than all the files in that directory. The other two are class loaders implemented by the Java language itself, including the extension ClassLoader (Extclassloader) and the Application class loader (Appclassloader), which is responsible for loading \lib\ext directories or system variables Java.ext.dirs The files in the specified directory. The application ClassLoader is responsible for loading files in the user's classpath. Users can load their classes directly using the Extension class loader or the system ClassLoader, but users cannot directly use the Launch class loader, except for these two kinds of loaders, where the user can also customize the class loader, as shown in the loading process:  

Note: The parent loader is not implemented by inheritance, but by combining it.  
We can verify this process through a program:

/** * Java学习交流QQ群:589809992 我们一起学Java! */public class Test {}public class TestMain { public static void main(String[] args) { ClassLoader loader = Test.class.getClassLoader(); while (loader!=null){ System.out.println(loader); loader = loader.getParent(); } }}

The running results of the above program are as follows:

As we can see from the results, by default, the user-defined class is loaded with Appclassloader, the Appclassloader's parent loader is Extclassloader, but the Extclassloader's parent loader is shown as empty. What is the reason for this? The reason is that the startup ClassLoader is part of the JVM, which is not implemented by the Java language and is not directly referenced in Java, so it returns NULL. But if so, how do you implement the parental delegation mechanism between the Extclassloader and the startup ClassLoader? We can refer to the source code:

Protected class<?> loadclass (String name, Boolean resolve) throws ClassNotFoundException {Synchronize D (Getclassloadinglock (name)) {First, checkIf theClassHasAlreadybeenLoaded class<?> c = findloadedclass (name);if (c = =NULL) {Long T0 = System.nanotime ();try {if (Parent! =NULL) {c = parent.loadclass (name,FALSE); }else {c = findbootstrapclassornull (name);}}catch (ClassNotFoundException e) {ClassNotFoundException thrownIfClassNotFoundFrom the non-Null parentClassLoader}if (c = =NULL) {If stillnot found, then invoke Findclass  In order //to find the class. Long T1 = System.nanotime (); c = findclass (name); //this is the defining class loader; record the stats Sun.misc.PerfCounter.getParentDelegationTime (). Addtime (T1-T0); Sun.misc.PerfCounter.getFindClassTime (). Addelapsedtimefrom (t1); Sun.misc.PerfCounter.getFindClasses (). increment (); }} if (Resolve) {resolveclass (c);} return C;} } 

From the source can be seen, Extclassloader and Appclassloader are inherited from the ClassLoader class, ClassLoader class through the LoadClass method to achieve parental delegation mechanism. The entire class loading process can be divided into the following three steps:

1. Find out if the corresponding class has been loaded.
2, if not loaded, then determine whether the current class loader's parent loader is empty, not empty delegate to the parent class to load, otherwise call the startup ClassLoader load (Findbootstrapclassornull and then call a native method).
3. If the second step fails to load, the current ClassLoader is called to load.

From the above program, it is clear how the extension class loader and the startup ClassLoader implement the delegate mode.

Now, let's verify another problem. We have just put the test class into a jar package, put it in the \lib\ext directory, and then run the above code again, the result is as follows:

Now, the class is no longer loaded through Appclassloader, but is loaded by Extclassloader. If we attempt to copy the jar package to \lib and attempt to load the class by launching the ClassLoader, we will find that the compiler cannot recognize the class because the startup ClassLoader must also be a file of a specific name to load, in addition to the specified directory.

Iii. Custom Class Loaders

Typically, we use the System class loader directly. However, sometimes we also need to customize the ClassLoader. For example, the application is to transfer the Java class byte code through the network, in order to guarantee the security, these bytecode has been encrypted processing, then the system ClassLoader cannot load it, so it needs to be implemented by the custom class loader. Custom class loaders are generally inherited from the ClassLoader class, from the above analysis of the LoadClass method, we only need to exercise rehabilitation Center rewrite Findclass method can be. Here we demonstrate the process of customizing the ClassLoader with an example:

Package com.paddx.test.classloading;Import java.io.*;/** * Created by Liuxp on 16/3/12. */PublicClassMyclassloaderExtendsClassLoader {private String root;Protected class<?>Findclass (String name)Throws ClassNotFoundException {byte[] Classdata = loadclassdata (name);if (Classdata = =NULL) {ThrowNew ClassNotFoundException (); }else {Return defineclass (name, Classdata,0, Classdata.length); } }PrivateByte[]loadClassData (String className) {string fileName = root + File.separatorchar + classname.replace ('. ', File.separatorchar) +". Class";try {InputStream ins =New FileInputStream (FileName); Bytearrayoutputstream BAOs =New Bytearrayoutputstream ();int buffersize =1024;byte[] Buffer =NewByte[buffersize];int length =0;while (length = ins.read (buffer))! =-1) {Baos.write (buffer,0, length); }return Baos.tobytearray (); }catch (IOException e) {e.printstacktrace ();}ReturnNull }Public StringGetroot () {return root; }PublicvoidSetroot (String root) {this.root = root;} public static void main (string[] args) {Myclassloader ClassLoader = new myclassloader (); Classloader.setroot ( "/users/liuxp/tmp"); class<?> TestClass = null; try {TestClass = Classloader.loadclass ( " Com.paddx.test.classloading.Test "); Object object = Testclass.newinstance (); System.out.println (Object.getclass (). getClassLoader ()); } catch (classnotfoundexception e) {e.printstacktrace ();} catch (instantiationexception e) {e.printstacktrace ();} catch (illegalaccessexception e) {e.printstacktrace ();}}     

Running the above program, the output is as follows:

The core of the custom ClassLoader is the acquisition of the bytecode file, and if it is an encrypted bytecode, the file must be decrypted in that class. Since this is just a demonstration, I did not encrypt the class file, so there is no decryption process. Here are a few things to note:

1, the file name passed here needs to be the full-qualified name of the class, that is, the com.paddx.test.classloading.Test format, because the DefineClass method is processed in this format.
2, it is best not to rewrite the LoadClass method, because it is easy to destroy the parental delegation mode.
3, this kind of Test class itself can be loaded by the Appclassloader class, so we can not put Com/paddx/test/classloading/test.class under the classpath. Otherwise, due to the existence of the parent delegation mechanism, the class is directly loaded by Appclassloader and not by our custom class loader.

Iv. Summary

The parent delegation mechanism can solve the unity problem of class loading well. For a class object, if the ClassLoader is different, even the same bytecode file, the generated class objects are not equal. That is, the class loader is equivalent to a namespace for a class object. The parent delegation mechanism ensures that the base class is loaded by the same classloader, which avoids the problem of generating different class objects with a single bytecode file that is loaded multiple times. But the parental delegation mechanism is only one of the implementations recommended by the Java specification, and it is not a mandatory requirement. In recent years, many of the technologies for hot deployment have not followed this rule, such as OSGi technology, which employs a mesh structure rather than a parental delegation mechanism.

Java class loading mechanism detailed

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.