Revisit Java's class loading mechanism

Source: Internet
Author: User

http://blog.csdn.net/hitxueliang/article/details/19992851

First of all, briefly say the ClassLoader

We know that the instructions for a virtual machine are stored in a class file with an extension of. class. So how do virtual machines invoke these. class files? Let's take a look at the steps the virtual machine performs:

1. The virtual machine has a mechanism for class loading that reads the class file from the data source, which can be a disk file or a file on the web, assuming that the Revenga to be loaded is testloader.

2. If the Testloader class has an instance of another class or a subclass of a class, which means that it is associated with or dependent on other classes, then the related classes are loaded

3. The main method in virtual machine execution Testloader

4. If there is a dependency on other classes in the main method, load the corresponding class.

The "Middleman" of the contact virtual machine and our program is the ClassLoader, with what is loaded. The class loader has its own system. Each Java program has a minimum of three classloader:

Boot class Loader:

The boot ClassLoader is responsible for loading system classes, usually loaded from Rt.jar, and the boot ClassLoader is part of the virtual machine architecture, and implementations are usually implemented in C. The boot ClassLoader does not have a corresponding ClassLoader object, for example:

System.out.println ("----------Test boot class loader-------------");
SYSTEM.OUT.PRINTLN ("Class loader:" +class.class.getclassloader (). Getsystemclassloader ());
SYSTEM.OUT.PRINTLN ("Testloader loader:" +testloader.class.getclassloader ());
System.out.println ("Stirng class loader:" +string.class.getclassloader ());
System.out.println ("ArrayList class loader:" +arraylist.class.getclassloader ());
System.out.println ("----------Test boot class loader-------------\ n");

Then the corresponding results are as follows:

----------test the Boot class loader-------------
class loader: [email protected]
Testloader loader: [Email protected]
Class loader for stirng: null
Class loader for ArrayList: null
----------test the Boot class loader-------------

Obviously we know that arraylist,string and the basic types of encapsulation classes belong to Rt.jar, which is consistent with the results.

Extension class Loader:

The extension class loader is used to load extension classes from the Jre/lib/ext directory. You can put your jar in this directory, so there is no path problem, but there is a problem to note: If you put your jar under the Jre/lib/ext, if your class calls the system class or other extension classes, then you are on the job, because the extension class loader does not use the classpath, This causes you to be unable to find it, so consider circumventing this problem before using extension paths to resolve class file conflicts.

System class Loader:

The system ClassLoader is used to load the application class, and you can find the class in the jar specified inside the classpath.

The extension class loader and the System class loader are all implemented in Java, are all examples of urlclassloader, the diagram, you can see the figure below, can be seen here appclassloader is we printed on the System class loader, And he's the urlclassloader of the class.

Class loader Hierarchy

The class loader has a hierarchical structure that can be thought of as the default upper-level precedence principle. In addition to the boot class loader, there is a parent class loader for the ClassLoader. As a rule, each ClassLoader provides a job for its parent class loader, and if the parent cannot complete the task, he will do it himself. For example, if you want the system ClassLoader to load a string type, first the System class loader will let his father, the extension class loader to try to load, then the extension ClassLoader will let his father--boot class loader to try to load, the boot ClassLoader is the top layer, he saw this task is my dish, Then he will finish the task.

The loader hierarchy for the class is as follows

Although most of the time you don't have to worry about class loading hierarchies. Usually classes are loaded by the needs of other classes, and the process is transparent to most people. But if you want to interfere with the process, it's also possible. The following describes how to specify the loader yourself.

This is illustrated in a main function. Each thread has a reference to the ClassLoader of the class, called the context class loader.

Thread T=thread.currentthread ();
System.out.println ("The class loader of the current main thread is:" +t.getcontextclassloader ());
T.setcontextclassloader (New Myloader ("Hello World"));
ClassLoader Loader=t.getcontextclassloader ();
SYSTEM.OUT.PRINTLN ("Set loader, use its own class loader:" +t.getcontextclassloader ());

This first gets the class loader for the current thread, which is then specified as its own class loader.

This shows that the loader of the main thread is the System class loader. When a new thread is created, his context loader is set to the creator's context class loader. So if you don't intervene, it's still the system ClassLoader.

How do I implement my own classloader?

Implementing your own ClassLoader is actually very simple, just inherit the ClassLoader class, and then overwrite the Findclass method. When we call our class loader, first he will hand this work to his father, and the LoadClass method in the parent class will do it and find that the class has not been loaded or loaded before calling the Findclass method.

The tasks to be implemented by the Findclass method are:

1. Load byte code

2. Call the Definclass method of the parent class to provide the byte code to the virtual machine.

My loader

Import Java.io.ByteArrayOutputStream;
Import Java.io.FileInputStream;
Import java.io.FileNotFoundException;
Import java.io.IOException;




public class Myloader extends classloader{


Private String key;
Public Myloader (String key) {
This.key=key;
System.out.println (key+ ", his class loader is instantiated");
}
@Override
Protected class<?> Findclass (String name) throws ClassNotFoundException {
Byte[] Classbytes=null;
Classbytes=loadclassbytes (name);
Class<?> cl=defineclass (null, classbytes, 0, classbytes.length);
if (cl==null) {
SYSTEM.OUT.PRINTLN ("failure");
return null;
}
return CL;
}
Reads a file, returns a byte array
Private byte[] Loadclassbytes (String name) {
FileInputStream In=null;
try {
In=new FileInputStream (name);
Bytearrayoutputstream buffer=new Bytearrayoutputstream ();
int ch;
while ((Ch=in.read ())!=-1) {
byte b= (byte) ch;
Buffer.write (b);
}
In.close ();
return Buffer.tobytearray ();
} catch (FileNotFoundException e) {
TODO auto-generated Catch block
E.printstacktrace ();
} catch (IOException e) {
TODO auto-generated Catch block
E.printstacktrace ();
}
return null;
}
}

The class being loaded

public class Tobeload {


public static void Main (string[] args) {
System.out.println ("The loaded class Main method executes");
System.out.println (Args[0]);


}


}

Test class:

Import Java.io.File;
Import java.lang.reflect.InvocationTargetException;
Import Java.lang.reflect.Method;
Import java.util.ArrayList;




public class Testloader {


public static void Main (string[] args) throws ClassNotFoundException, Nosuchmethodexception, SecurityException, Illegalaccessexception, IllegalArgumentException, invocationtargetexception {
System.out.println ("----------Test boot class loader-------------");
SYSTEM.OUT.PRINTLN ("Class loader:" +class.class.getclassloader (). Getsystemclassloader ());
SYSTEM.OUT.PRINTLN ("Testloader loader:" +testloader.class.getclassloader ());
System.out.println ("Stirng class loader:" +string.class.getclassloader ());
System.out.println ("ArrayList class loader:" +arraylist.class.getclassloader ());
System.out.println ("----------Test boot class loader-------------\ n");


File F=new file ("E://workspace//javase//mytest//bin//tobeload.class");

Thread T=thread.currentthread ();
System.out.println ("The class loader of the current main thread is:" +t.getcontextclassloader ());
T.setcontextclassloader (New Myloader ("Hello World"));
ClassLoader Loader=t.getcontextclassloader ();
SYSTEM.OUT.PRINTLN ("Set loader, use its own class loader:" +t.getcontextclassloader ());

Class<?> C=loader.loadclass (F.getabsolutepath ());
Method[] M=c.getmethods ();
M[0].invoke (null, (Object) New string[]{"1"});



}


}

Revisit Java's class loading mechanism

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.