[New Features of Java 5] Class Loader

Source: Internet
Author: User

[New Features of Java 5] Class Loader
Classloader Overview

The Class loader is responsible for loading all classes. The system generates a java. lang. Class instance for all classes loaded into the memory. Once a class is added to JVM, the same class will not be added again. Just as an object has a unique identifier, a class loaded into JVM also has a unique identifier. In Java, a class uses its fully qualified class name (including the package name and Class Name) as its identifier. However, in JVM, A class uses its fully qualified class name and its class loader as its unique identifier.

In the following example, two Person classes with the same name are completely different in JVM, and they are not compatible because the class loaders are different.

The Code is as follows:

Defines a Person class.
public class Person {    private Person instance;     public void setPerson(Object instance) {         this.instance = (Person) instance;     } }
Compile a test method to test how to get different Class instances by loading the Person Class through two different Class loaders.
    @Test    public void ClassIdentityTest() throws Exception{        String classDataRootPath = WebRoot\WEB-INF\classes;         FileSystemClassLoader fscl1 = new FileSystemClassLoader(classDataRootPath);         FileSystemClassLoader fscl2 = new FileSystemClassLoader(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 will not think it is the same because the Class instances are obtained through different Class loaders.

Class Loader category

When JVM is started, an initial class loader hierarchy consisting of three class loaders is formed.

Bootstrap ClassLoader: Root loader. Extension ClassLoader: extends the class loader. System ClassLoader: System class loader.

Bootstrap ClassLoader is called a Bootstrap (or original or root) Class Loader, which loads the Java core class. In jvm, when executing the java.exe command, you can use the-Xbootclasspath option or the-D option to specify the system attribute value of sun. boot. class. path to specify the attached class to be loaded. The root loader is very special. It is not a subclass of java. lang. ClassLoader, but implemented by JVM itself.

@ Test public void BootstrapTest () {// obtain all URL arrays loaded by the root loader. URL [] urls = sun. misc. launcher. getBootstrapClassPath (). getURLs (); // traverses all urls loaded by the output root loader for (int I = 0; I <urls. length; I ++) {System. out. println (urls [I]. toExternalForm ());}}

Extension ClassLoader is called an Extension class loader, which is responsible for loading the Extension directory of JRE (% JAVA_HOME %/jre/lib/ext or by java. ext. JAR package class in the directory specified by the dirs system attribute. This method can be used to expand new functions other than the core class for Java. You only need to package your own classes into a JAR file and then put them in the % JAVA_HOME %/jre/lib/ext path.

@ Test public void ExtensionTest () throws Exception {// located in jre/lib/ext/dnsns. jar DNSNameService dnsNameService = new DNSNameService (); System. out. println (dnsNameService. getClass (). getClassLoader ());}

System ClassLoader is called a System or application Class Loader. It is responsible for loading the-classpath option from the java command, java at JVM startup. class. path System attribute, or the JAR package and path specified by the CLASSPATH environment variable. The program can use the static method getSystemClassLoader () of ClassLoader to obtain the system class loader. If not specified, the user-defined class loaders use the system class loaders as the parent loaders.

@ Test public void SystemTest () throws Exception {// obtain the Instance Object ClassLoaderTest classLoaderTest = new ClassLoaderTest (); System. out. println (classLoaderTest. getClass (). getClassLoader ());}

The following is the hierarchy of the four types of loaders in JVM:

@ Test public void ClassLoaderTreeTest () throws Exception {// obtain the ClassLoader classLoader ClassLoader = ClassLoaderTest of the current class. class. getClassLoader (); // determines whether the class loader is empty. while (classLoader! = Null) {// print the name of the current class loader System. out. print (classLoader. getClass (). getName () +->); // obtain the parent class classLoader = classLoader of the current class loader. getParent ();} System. out. println (classLoader );}

The above code shows the hierarchy of class loaders in JVM. The final result is the willingness to output null because the root loader is not provided by Java but by JVM, so it cannot be obtained.

Class Loading Mechanism

There are three main JVM classloaders:

Overall responsibility. The so-called full responsibility means that when a Class loader is responsible for loading a Class, the Class loader will also be responsible for loading the Class dependent and referenced other classes, unless you explicitly use another class loader for loading. Parent class delegate. The so-called parent Class delegate is to let the parent Class loader view load the Class first. Only when the parent Class loader cannot load the Class attempt to load the Class from its own Class path. Cache mechanism. The cache mechanism ensures that all loaded classes are cached. When a Class is required in the program, the Class Loader first searches for the Class from the cache area, only when this Class object does not exist in the cache area will the system read the binary data corresponding to this Class, convert it into a Class object, and store it in the cache area. This is why the modifications made by the program take effect only after JVM is restarted after the Class is modified. Custom Class Loader

All class loaders except the root class loaders in JVM are instances of the ClassLoader subclass. You can extend the ClassLoader subclass, and override the methods provided by the ClassLoader to implement the custom class loader.

The ClassLoader class has the following two key methods:

LoadClass (String name, boolean resolve): This method is the entry point of ClassLoader. The Class is loaded according to the specified name. The system calls the ClassLoader method to obtain the Class object corresponding to the specified Class. FindClass (String name): searches for classes based on the specified name.

Because the loadClass () method is executed in step 1) The findLoadedClass () method is used to check whether the class has been loaded. 2) The loadClass () method is called in the parent class loader. 3) Call the findClass () method to find the class. Override the findClass () method can avoid the parent class delegation and buffer mechanism of the default Class Loader. Here we recommend that you override the findClass () method.

The following is a file system class loader used to load the Java byte code stored in the file system.

public class FileSystemClassLoader extends ClassLoader {    private String rootDir;    public FileSystemClassLoader(String rootDir) {        this.rootDir = rootDir;    }    protected Class
   findClass(String name) throws ClassNotFoundException {        byte[] classData = getClassData(name);        if (classData == null) {            throw new ClassNotFoundException();        }        else {            return defineClass(name, classData, 0, classData.length);        }    }    private byte[] getClassData(String className) {        String path = classNameToPath(className);        try {            InputStream ins = new FileInputStream(path);            ByteArrayOutputStream baos = new ByteArrayOutputStream();            int bufferSize = 4096;            byte[] buffer = new byte[bufferSize];            int bytesNumRead = 0;            while ((bytesNumRead = ins.read(buffer)) != -1) {                baos.write(buffer, 0, bytesNumRead);            }            return baos.toByteArray();        } catch (IOException e) {            e.printStackTrace();        }        return null;    }    private String classNameToPath(String className) {        return rootDir + File.separatorChar                + className.replace('.', File.separatorChar) + .class;    }}
 

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.