This article focuses on the Java ClassLoader and the simple classloader that you write yourself.
Several ClassLoader can be installed in a Java virtual machine, and the default ClassLoader has 3:bootstrap,extclassloader,appclassloadeR. Different classes record classes that are responsible for loading different locations. The ClassLoader itself is also a Java class, because the ClassLoader itself is loaded by the ClassLoader itself, and obviously must have the first ClassLoader, which is not a Java class, and this ClassLoader is bootstrap. The ClassLoader is organized as a parent-child tree, and when you instantiate each classloader, you need to specify a parent ClassLoader or a system class loader as its parent classloader. Lists the relationship of the ClassLoader and its scope of jurisdiction:
The following code is written to test the following relationship:
ClassLoader loader = ClassLoaderDemo.class.getClassLoader (); while (loader! = null) {SYSTEM.OUT.PRINTLN ( Loader.getclass (). GetName ()); loader = Loader.getparent ();}
Running the above code gives the following results:
Sun.misc.launcher$appclassloader
Sun.misc.launcher$extclassloader
From the above results can be analyzed: the topmost class loader gets null, why is it null? Because this classloader is not a Java class, it is written in C. This verifies the relationship as above.
In addition to introducing a class loader appointment mechanism , such as to load a class, the subclass loader will ask the parent ClassLoader is loaded, directly traced to the upper level of the ClassLoader, if the parent class loader can not load, then the source class loader to load again, No more loading will run out of the classnotfoundexception exception, and will not find the sub-class loader to load. It is possible to do experiments to verify this, such as placing a class loader of the class that is below the current classpath into a jar in the Jre/lib/ext directory and running to view the output. Why is there an appointment mechanism for ClassLoader? Mainly for security reasons, the user can customize the class loader, it is difficult to join the appointment mechanism without classloader to ensure that only one byte of a class in memory, if it is delegated to the parent class loader processing, only the parent class loader has been loaded or can be loaded to the parent loader.
When Java virtual machines load a class, who does it send to load?
- The class loader of the current thread is first loaded to load the first class of a thread;
- If Class A refers to Class B, the Java Virtual machine will use the class loader of Class A To load Class B
- You can also use the Classloader.loadclass () method directly to specify a class loader to load a class
How do you load a class in Java? In Java, the introduction of the class loader to load the class, the corresponding class is ClassLoader, this class is an abstract class, the custom ClassLoader needs to inherit this class, from the API, you can see that the class loader loads the class using the method of ClassLoader, This method has some algorithms for loading classes, the custom ClassLoader needs to implement the public class Findclass (String name) method, the parameter is the class name, and a class object is returned. ClassLoader implements a DefineClass method that loads classes based on a byte array of the classes you provide,ClassLoader uses the template method design pattern.
The following code to define the class loader, first through the Myclassloader Main method to encrypt a compiled class, and then the class loader loading and then decryption, encryption and decryption algorithm is simple, only use the XOR
Package Cn.zq.demo;import Java.io.bytearrayoutputstream;import Java.io.fileinputstream;import Java.io.fileoutputstream;import Java.io.inputstream;import Java.io.outputstream;public class MyClassLoader extends classloader{/** * class file has the extension */private static final String Class_ext = ". Class"; The path where the/** * class is located. */private String Path;publi C Myclassloader (String path) {super (); this.path = path;} /** * This method is called by the JVM */public class<?> findclass (String name) throws ClassNotFoundException {byte[] b = loadClassData (nam e); return defineclass (name, b, 0, b.length);} /** * Read class file * @param the full name of the name class * @return binary byte array */private byte[] loadClassData (String name) {FileInputStream FIS = null;try {name = Name.substring (Name.lastindexof (".") + 1); fis = new FileInputStream (path + "\ \" + name + class_ext); Bytearrayoutputstream BAOs = new Bytearrayoutputstream () cypher (FIS, BAOs); return Baos.tobytearray ();} catch (Exception e) {throw new RuntimeException (e);} Finally{if (FIS! = null) {try {fis.close ();} catch (ExCeption e) {throw new RuntimeException (e);} Finally{fis = null;}}} private static void Cypher (InputStream in, outputstream out) throws Exception{int B = -1;while ((b = In.read ())! =-1) {O Ut.write (b ^ 0XFF);}} public static void Main (string[] args) throws exception{string Srcpath = Args[0]; The source class file is located in the same path as String filedir = Args[1]; The directory where the encrypted class file is located fileinputstream fis = new FileInputStream (Srcpath); String filename = srcpath.substring (srcpath.lastindexof ("\ \") + 1); String DestPath = filedir + "\ \" + filename; FileOutputStream fos = new FileOutputStream (destpath); Cypher (FIS, FOS); Fos.close (); Fis.close ();}}
Package Cn.zq.demo;public class Data {public String toString () {return "My data!";}}
Package Cn.zq.demo;public class Classloaderdemo {public static void main (string[] args) throws Exception {ClassLoader load ER = ClassLoaderDemo.class.getClassLoader (); while (loader! = null) {System.out.println (Loader.getclass (). GetName ()); Loader = Loader.getparent ();} Myclassloader Myclassloader = new Myclassloader ("Classfile"), Object o = Myclassloader.loadclass ("Cn.zq.demo.Data"). Newinstance (); System.out.println (O.getclass (). GetName () + "+" + O);}
The exception that is possible to run the above code is:
java.lang.ClassFormatError:Incompatible Magic Value 889275713 in class file Cn/zq/demo/data
indicates that the class file is not valid ,
Run the above program if the result is: Cn.zq.demo.data->my data!
so congratulations, your program can run through, your class loader successfully run , and finally give the project file address, we need to be able to download, if you encounter any problems can be timely contact me, at any time for you to answer all kinds of problems.
Source Code Address
Java class Loader