In addition to the custom class loading, the JVM has three kinds of loaders and is loaded with a load mechanism of a parent delegate.
--Starting the ClassLoader, also known as the root loader, is a native method, implemented using C + +. In Java we use the null identifier, which is used to load the class that comes with the JDK.
--Extension class loader for loading JDK extension classes
--System class loader for loading classes under the Classpath directory
The above mentioned three kinds of loaders, is the existence of a parent-child relationship, that is, the system ClassLoader will delegate the extension loader, if the extension loader can not load the class, then by the System class loader to load. Note that the parent-child relationship here does not refer to an inheritance relationship, but rather a combination of relationships. Why use this parent-delegate loading mechanism?
In the final analysis is a security considerations, if there is a user-defined class loader Myclassloader, and then the user uses a non-javac way to generate bytecode files, such a bytecode file may exist such a class java.lang.string, This class is then loaded by Myclassloader, and if it is not delegated to the root loader, it really makes this pseudo-string replace the JDK's own class file.
Implementing a custom ClassLoader simply inherits the ClassLoader, overriding the Findclass () method
ImportJava.io.ByteArrayOutputStream;ImportJava.io.FileInputStream;ImportJava.io.FileOutputStream;ImportJava.io.InputStream;/*** @desc *@authorCHENQM * @date February 17, 2016*/ Public classMyclassloaderextendsClassLoader {PrivateString name;//the name of the class loader PrivateString Path = "d:\\";//the path of the load class PrivateString FileType = ". Class";//class file's extension PublicMyclassloader (String name) {Super(); This. Name =name; } PublicMyclassloader (ClassLoader parent,string name) {Super(parent);//explicitly develop a parent loader for this classloader } PublicString GetPath () {returnpath; } Public voidSetPath (String path) { This. Path =path; } @Override PublicClass<?> Findclass (String name)throwsclassnotfoundexception{byte[] data = This. loadClassData (name); return This. defineclass (name, data, 0, data.length); } Private byte[] loadClassData (String name) {InputStream is=NULL; byte[] data =NULL; Bytearrayoutputstream BAOs=NULL; Try{Name= Name.replace (".", "\ \")); is=NewFileInputStream (path + name +FileType); BAOs=NewBytearrayoutputstream (); intCH =0 ; while( -1! = (ch =Is.read ())) {baos.write (CH); } Data=Baos.tobytearray (); }Catch(Exception e) {e.printstacktrace (); }finally{ Try{is.close (); Baos.close (); }Catch(Exception e) {e.printstacktrace (); } } returndata; } @Override PublicString toString () {//TODO auto-generated Method Stub returnname; } Public Static voidMain (string[] args)throwsexception{Myclassloader loader1=NewMyclassloader ("Loader1"); Loader1.setpath ("D:\\myapp\\serverlib\\"); Myclassloader Loader2=NewMyclassloader (Loader1, "Loader2"); Loader2.setpath ("D:\\myapp\\clientlib\\"); Myclassloader Loader3=NewMyclassloader (NULL, "Loader3"); Loader3.setpath ("D:\\myapp\\otherlib\\"); Test (LOADER1); Test (LOADER2); Test (LOADER3); } Public Static voidTest (ClassLoader Loader)throwsexception{Class clazz= Loader.loadclass ("Simple"); Object o=clazz.newinstance (); }}
Here I have customized a class loader for loading simple classes
/** * @desc @author CHENQM */ Public class Simple { publicly simple () { System.out.println ("Sample was loaded by:" + this. GetClass (). getClassLoader ()); New Dog (); System.out.println ("Dog is loaded by:" +Dog.getclass (). getClassLoader ());} }
Give the Dog class:
/** * @desc @author CHENQM */ Public class Dog {}
Then put the Dog.class and Simple.class files into D:\myapp\serverlib and D:\myapp\clientlib, and put the Myclassloader file under D:\myapp\otherlib.
Go to D:\myapp\otherlib execute Java myclassloader
Get results:
D:\myapp\otherlib>java Myclassloader
Sample:loader1
Dog:loader1
Sample:loader1
Dog:loader1
Java.io.filenotfoundexception:d:\myapp\syslib\simple.class (the system cannot find the specified text
Thing )
For a simple analysis, note the main method of Myclassloader, which has three custom ClassLoader Loader1 (the parent loader is the system ClassLoader), Loader2 (the parent loader is loader1), and Loader3 (the parent loader is the root loader).
Test method: Loads the simple class with the specified class loader.
--with Loader1 to load simple class, Loader1 's parent loader is the System class loader, the system class loader certainly can't load simple class, why? As I said earlier, the system ClassLoader is used to load classes under Classpath, and what is classpath default? "." is the current path, and the current path does not exist in the simple class, so it is loaded by Loader1.
--loader2 's parent loader is loader1, so according to the parent-delegate loading mechanism, the simple class should be loaded by Loader1.
--loader3 's parent loader is the root loader, and the root loader does not load our custom class files, so the load is given to Loader3, but the Loader3 directory, There is no Simple.class file, no way, father can not do, oneself also can not do, that only throws abnormal.
JVM Custom class Loader