I. Overview
(a) ClassLoader (class loader )
A tool for dynamically loading Java classes, which is itself a Java class.
(ii) Class loader role
Responsible for loading the Java class byte code into the Java virtual machine.
(c) Java class Loader
1, Java Virtual machine can install multiple ClassLoader, the system default three main class loader, each class loader is responsible for loading a specific location of the class:
(1) BootStrap (BootStrap class loader): It is used to load Java core library, is implemented with native code, does not inherit from Java.lang.ClassLoader.
(2) Extclassloader (Extensions class loader): It is used to load the Java extension library. The implementation of the Java virtual machine provides an extension library directory. The ClassLoader finds and loads the Java class in this directory.
(3) Appclassloader (System class loader): It loads Java classes based on the Classpath (CLASSPATH) of the Java application. In general, Java-applied classes are loaded by it. It can be obtained by Classloader.getsystemclassloader ().
2, BootStrap
The class loader is also a Java class, because the class loader of other Java classes is also loaded by the ClassLoader itself, and it is clear that the first ClassLoader is not a Java class, which is bootstrap.
3. Class loader demo, code example:
1 Public classClassloaderdemo {2 Public Static voidMain (string[] args) {3 System.out.println (4Classloaderdemo.class. getClassLoader (). GetClass (). GetName ()5);//Sun.misc.launcher$appclassloader, indicated by Appclassloader load6System.out.println (System.class. getClassLoader ());//NULL, which indicates that the system is loaded by Rootstrap when the class is7 }8}
(iv) tree-like structure and jurisdiction of class loaders
Demonstrates the tree-like structure of the ClassLoader, with the following code examples:
1 Public classClassloadertree {2 Public Static voidMain (string[] args) {3ClassLoader loader = Classloadertree.class. getClassLoader ();4 while(Loader! =NULL) {5 System.out.println (loader.tostring ());6Loader =loader.getparent ();7 }8 }9}
Second, the delegation mechanism of class loader
(i) The process of loading a class
When the Java virtual machines load a class, exactly which classloader to use to load it?
(1) First, the class loader of the current thread loads the first class in the thread.
(2) If a refers to Class B (inheriting or using B), the Java Virtual machine will load Class B with the class loader of the load class.
(3) You can also call ClassLoader's Loaderclass () method directly to specify a class loader to load a class.
(ii) Delegate of class loader
1, each class loader load class, and the first delegate to the upper class loader.
(1) First, the class loader initiator is commissioned at the level up to bootstrap;
(2) from the bootstrap loader began to find, found a direct return, did not find another level down to return to let its child loader to find;
(3) Always return to the initiator, the initiator is not found, then throw classnotfoundexception, instead of looking for the subclass of the initiator class loader.
2, Interview questions: Can you write a Java.lang.System class?
(1) It is usually not possible, because of the class loader's delegation mechanism, the system is first class-level delegated to the top bootstrap, Because bootstrap loads a class in Rt.jar in its specified directory, Rt.jar has the system class, it is loaded directly without loading the custom system class.
(2) But there is a way to load the custom system class, at this point can not be handed over to the higher load, need to be loaded with a custom class loader, this requires a special method to load the custom system class.
Iii. Custom Class Loaders
(i) overview
1. The custom ClassLoader must inherit ClassLoader, overwriting the Findclass (String name) method, without overwriting the LoadClass () method.
2, the principle of class loader
(1) LoadClass () will be delegated to the parent first, when the parent is not found, then return, call the Findclass (String name) method, that is, the custom ClassLoader to find. So just overwrite the Findclass method, you can implement the purpose of loading the class with a custom class loader.
(2) The general custom ClassLoader will put the classes that need to be loaded in their own specified directory, and Java already have the ClassLoader is not known to your directory, so will not be found. This will call your Findclass () method and use your custom class loader to go to the specified directory load class.
3. Template Method Design mode
The template method design pattern retains the flow in the LoadClass () method (the process is to find the parent first, and then call the custom ClassLoader), so just overwrite the Findclass () method and implement the local details.
4. How do I convert the contents of a class file into bytecode when I get the binary data from the class file?
ClassLoader provides a protected class<?> defineclass (String name, byte[] B, int off, int len) method, which simply passes the class file into byte code.
(ii) Programming steps
1, write a simple encryption of the file contents of the program
2, has written a own class loader, can be implemented to encrypt the class to load and decrypt.
3, write a program, call the class loader load class, in the source program can not define reference variables with the class name, because the compiler does not recognize the class, in addition to using the ClassLoader LoadClass method, you can also use the context class loader or the System class loader to set the thread, Then use Class.forName.
(iii) Coding steps
1, the class file without the package name is encrypted, the encryption results stored in another directory, for example: Java myclassloader mytest.class F:\itcast
2, run the Load class program, the results can be loaded normally, but the printed class loader name is Appclassloader:java myclassloader MyTest F:\itcast
3, replace the class file in the CLASSPATH environment with the encrypted class file, then perform the previous operation on the problem, the error indicates that the Appclassloader class loader failed to load.
4, delete the CLASSPATH environment of the class file, and then perform the previous operation is no problem.
(iv) Custom class loader, code implementation (Zhang Xiaoxiang teacher explained)
1. Define a test class: Classloaderattachment
1 // defines a test class that inherits date and is used to load 2 Import java.util.Date; 3 Public class extends date{4 Public String toString () {5 return "Hello,itcast"; 6 }7 }
2, custom class loader: Myclassloader, inherit ClassLoader, overwrite Findclass () method.
1 ImportJava.io.ByteArrayOutputStream;2 ImportJava.io.FileInputStream;3 ImportJava.io.FileOutputStream;4 ImportJava.io.InputStream;5 ImportJava.io.OutputStream;6 Public classMyclassloaderextendsclassloader{7 Public Static voidMain (string[] args)throwsException {8String Srcpath = args[0];9String DestDir = args[1];TenFileInputStream FIS =NewFileInputStream (srcpath); OneString destfilename = srcpath.substring (srcpath.lastindexof ("\ \") +1); AString Destfilepath = destdir+ "\ \" +destFileName; -FileOutputStream fos =NewFileOutputStream (destfilepath); -Cypher (Fis,fos);//Encrypt class byte code the fis.close (); - fos.close (); - } - //Encryption Method + Private Static voidCypher (InputStream Ips,outputstream OPS)throwsexception{ - intb =-1; + while((b = ips.read ())!=-1){ AOps.write (B^0xff); at } - } - - PrivateString Classdir; - - @Override in protectedClass<?> Findclass (String name)throwsClassNotFoundException { -String classfilename = classdir + "\ \" + name.substring (Name.lastindexof ('. ') +1) + ". Class"; to Try { +FileInputStream FIS =NewFileInputStream (classfilename); -Bytearrayoutputstream BOS =NewBytearrayoutputstream (); theCypher (Fis,bos);//decryption * fis.close (); $System.out.println ("AAA");Panax Notoginseng byte[] bytes =Bos.tobytearray (); - returnDefineClass (Bytes, 0, bytes.length); the}Catch(Exception e) { + e.printstacktrace (); A } the return NULL; + } - $ PublicMyclassloader () {} $ PublicMyclassloader (String classdir) { - This. Classdir =Classdir; - } the}
3. Define class Load Test class: Classloadertest, Test custom class Loader
1 Importjava.util.Date;2 Public classClassloadertest {3 Public Static voidMain (string[] args)throwsException {4Class Clazz =NewMyclassloader ("Itcastlib"). LoadClass ("Cn.itcast. Day2. Classloaderattachment " ) ;5Date D1 =(Date) clazz.newinstance ();6 System.out.println (d1);7 }8}
Dark Horse Programmer--"Java High Technology"--class loader