[Java5 new feature] class loader

Source: Internet
Author: User

Class Loader Overview

The ClassLoader is responsible for loading all classes, and the system generates an Java.lang.Class instance for all classes that are loaded into memory. Once a class is added to the JVM, the same class is not added again. Just as an object has a unique identity, a class that is loaded into the JVM also has a unique identity. In Java, a class is identified with its fully qualified class name (including the package name and class name), but in the JVM, a class is uniquely identified with its fully qualified class name and its class loader.

For example, the two person classes with the same name in the JVM are completely different and incompatible with each other because the ClassLoader is different.

The above situation is translated into code as follows:

    • Defines a person class.
publicclass Person {    private Person instance;     publicvoidsetPerson(Object instance) {         this.instance = (Person) instance;     } }
    • Write a test method for testing to get different class instances by loading the person class with two different ClassLoader.
    @Test     Public void classidentitytest()throwsexception{String Classdatarootpath ="Webroot\\web-inf\\classes"; Filesystemclassloader FSCL1 =NewFilesystemclassloader (Classdatarootpath); Filesystemclassloader Fscl2 =NewFilesystemclassloader (Classdatarootpath); String ClassName ="App.java.classloader.Person";Try{class<?> Class1 = Fscl1.findclass (ClassName);             Object obj1 = Class1.newinstance ();             class<?> Class2 = Fscl2.findclass (className);             Object obj2 = Class2.newinstance (); Method Setsamplemethod = Class1.getmethod ("Setperson", Java.lang.Object.class);         Setsamplemethod.invoke (Obj1, OBJ2); }Catch(Exception e)         {E.printstacktrace (); }     }
    • After the above code is run, the following error is reported, indicating that although the class names of the two objects are the same, the JVM does not consider the same as having a class instance through different ClassLoader.

Class loader classification

When the JVM starts, it forms an initial class loader hierarchy consisting of three ClassLoader.

    • Bootstrap ClassLoader: Root class loader.
    • Extension ClassLoader: Extension class loader.
    • System ClassLoader: Class loader.

Bootstrap ClassLoader is called the boot (or primitive or root) ClassLoader, which is responsible for loading the core classes of Java. In the JVM, when you execute the java.exe command, use the-xbootclasspath option or specify the Sun.boot.class.path system property value by using the-D option to specify that additional classes are loaded. The root ClassLoader is very special, it is not a subclass of Java.lang.ClassLoader, but is implemented by the JVM itself.

    @Test    publicvoidBootstrapTest(){        // 获取根类加载器所加载的全部URL数组        URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();        // 遍历输出根类加载器加载的全部URL        for (int0; i < urls.length; i++) {            System.out.println(urls[i].toExternalForm());        }    }

Extension ClassLoader is known as the extension ClassLoader, which is responsible for loading the class of the jar package in the JRE's extended directory (%java_home%/jre/lib/ext or the directory specified by the Java.ext.dirs system properties). In this way, you can extend new functionality outside of the core class to JAVA, just package your own classes into jar files and put them in the%java_home%/jre/lib/ext path.

    @Test    publicvoidExtensionTestthrows Exception{        // 位于jre/lib/ext/dnsns.jar        new DNSNameService();        System.out.println(dnsNameService.getClass().getClassLoader());    }

System ClassLoader, known as the systems or application ClassLoader, is responsible for loading the-classpath option from Java commands, Java.class.path System Properties, or the jar package and class path specified by the CLASSPATH environment variable when the JVM starts. The program can obtain the system ClassLoader by ClassLoader static method Getsystemclassloader (). If not specified, the user-defined ClassLoader is used as the parent loader for the System class loader.

    @Test    publicvoidSystemTestthrows Exception{        // 获取当前类的实例对象        new ClassLoaderTest();        System.out.println(classLoaderTest.getClass().getClassLoader());    }

The following is the hierarchy of the 4 kinds of loaders in the JVM:

 @Test public  void  classloadertreetest  () throws exception{//gets the class loader of the current class  ClassLoader ClassLoader = ClassLoaderTest.class.getClassLoader ();        //determine if the ClassLoader is empty  while  (ClassLoader! = null ) {//print the name of the current class loader  System. out . Print (Classloader.getclass (). GetName () + "-"            );        //gets the parent of the current class loader  ClassLoader = Classloader.getparent (); } System.    out . println (ClassLoader); }

The class loader hierarchy in the JVM can be seen in the code above. The final output is null because the root classloader is not provided by Java, but is provided by the JVM, so it cannot be obtained.

Class loading mechanism

There are three main types of JVM loader mechanisms:

    • Overall responsibility. The so-called overall responsibility is that when a classloader is responsible for loading a class, other classes that the class relies on and references will also be loaded by the ClassLoader, unless explicitly loaded with another classloader.
    • The parent class delegate. The so-called parent class delegate is to have the parent ClassLoader view load the class before attempting to load it from its own classpath only if the parent class loader cannot load it.
    • Caching mechanism. The caching mechanism will guarantee that all loaded classes will be cached, and when a class is needed in the program, the ClassLoader will first search for the class from the buffer, and the binary data of that class is only read when the object does not exist in the buffer. and convert it into a class object, which is stored in the buffer. This is why after modifying class, the JVM must be restarted and the changes made by the program will not take effect.
Custom Class Loaders

All class loaders outside the root class loader in the JVM are instances of the ClassLoader subclass, which can be implemented by extending the subclass of ClassLoader and overriding the methods provided by the ClassLoader to implement a custom ClassLoader.

The ClassLoader class has the following two key methods:

    • LoadClass (String name, Boolean resolve): This method is the entry point for ClassLoader, which loads the class according to the specified name, and the system calls the ClassLoader method to get the class object corresponding to the specified class.
    • Findclass (String name): Finds the class based on the specified name.

Because the LoadClass () method performs step 1), the Findloadedclass () method is used to check whether the class has already been loaded. 2) Call the LoadClass () method in the parent class loader. 3) Call the Findclass () method to find the class. Overriding the Findclass () method avoids the default class loader's parent class delegate and buffering mechanism, which is recommended to override the Findclass () method.

The following implements a file system ClassLoader for loading Java byte code stored on the file system.

 Public  class filesystemclassloader extends ClassLoader {    PrivateString RootDir; Public Filesystemclassloader(String RootDir) { This. RootDir = RootDir; }protectedClass<?>Findclass(String name)throwsclassnotfoundexception {byte[] Classdata = Getclassdata (name);if(Classdata = =NULL) {Throw NewClassNotFoundException (); }Else{returnDefineClass (name, Classdata,0, classdata.length); }    }Private byte[]Getclassdata(String className) {String path = Classnametopath (ClassName);Try{InputStream ins =NewFileInputStream (path); Bytearrayoutputstream BAOs =NewBytearrayoutputstream ();intBufferSize =4096;byte[] buffer =New byte[BufferSize];intBytesnumread =0; while((Bytesnumread = ins.read (buffer))! =-1) {baos.write (buffer,0, Bytesnumread); }returnBaos.tobytearray (); }Catch(IOException e)        {E.printstacktrace (); }return NULL; }PrivateStringClassnametopath (String className) {        returnRootDir + File.separatorchar + classname.replace ('. ', File.separatorchar) +". Class"; }}

Reprint NOTE: Please indicate the author and the original link, thank you!

[Java5 new feature] class loader

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.