Java class loader and java class loading
This article mainly introduces the java class loader and write your own simple class loader.
Multiple class loaders can be installed in the Java Virtual Machine. The default class loaders include BootStrap, ExtClassLoader, and AppClassLoader. Different Class records are responsible for loading classes in different locations. The Class Loader itself is also a java class, because the Class Loader itself must also be loaded by the class loader. It is obviously necessary to have the first class loader, which is not a java class, the class loader is BootStrap. The class loader is organized based on the parent-child tree relationship. when instantiating each class loader, you must specify a parent class loader or use the system class loader as the parent class loader. Lists the relationships between class loaders and their jurisdictions:
Run the following code to test the above relationship:
ClassLoader loader = ClassLoaderDemo.class.getClassLoader();while( loader != null){System.out.println(loader.getClass().getName());loader = loader.getParent();}
Run the above code to get the following results:
Sun. misc. Launcher $ AppClassLoader
Sun. misc. Launcher $ ExtClassLoader
From the above results, we can see that the top-level classloader obtains null. Why is it null? This class loader is written in c instead of a java class. The above relationship is verified.
In addition, this article introduces the appointment mechanism of a Class Loader. For example, when a class is to be loaded, The subclass loader will ask the parent class loader to load the class and directly trace back to the class loader at the upper level, if neither of the parent class loaders can be loaded, the originating class loaders will be loaded again. If the parent class loaders cannot be loaded, the ClassNotFoundException will run out, rather than the subclass loaders. You can do experiments to verify this. For example, you can compress a class under the current class path (this class mainly loads the Class Loader) into a jar and put it in the jre/lib/ext directory, run the command to view the output result. Why is there an appointment mechanism for the class loader? Mainly for security considerations, you can customize the Class Loader. By adding a mechanism without class loaders, it is difficult to ensure that only one bytecode of A Class exists in the memory, if it is assigned to the parent class loader for processing, it is handed over to the parent class loader only after the parent class loader has been loaded or can be loaded.
Who will attach a class to a Java Virtual Machine?
- First, the class loader of the current thread loads the first class of the thread;
- If Class A references Class B, the Java virtual machine uses the class loader that loads Class A to load Class B.
- You can also directly use the ClassLoader. loadClass () method to specify a class loader to load a class.
How does one load classes in java? The class loader is introduced in java to load classes. The corresponding class is ClassLoader and this class is an abstract class. The custom Class Loader must inherit this class. From the api, we can see that, the ClassLoader method is used when the Class loader loads the Class. This method has some algorithms for loading the Class. The custom Class Loader must 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 internally. This Class loads the Class Based on the byte array of the Class you provide. ClassLoader uses the template method design mode.
The code for the custom class loader is as follows. The main method of MyClassLoader is used to encrypt a compiled class and decrypt it when the class loader is loaded, the encryption and decryption algorithm is simple, and only exclusive or
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 extension */private static final String CLASS_EXT = ". class ";/*** path of the class. */private String path; public MyClassLoader (String path) {super (); this. path = path;}/*** this method is called by jvm Use */public Class <?> FindClass (String name) throws ClassNotFoundException {byte [] B = loadClassData (name); return defineClass (name, B, 0, B. length);}/*** read the class file * @ param name full name * @ return binary byte array */private byte [] loadClassData (String name) {FileInputStream FCM = null; try {name = name. substring (name. lastIndexOf (". ") + 1); FCM = new FileInputStream (path +" \ "+ name + CLASS_EXT); ByteArrayOutputStream baos = new B YteArrayOutputStream (); cypher (FCM, baos); return baos. toByteArray ();} catch (Exception e) {throw new RuntimeException (e);} finally {if (FS! = Null) {try {FS. close () ;}catch (Exception e) {throw new RuntimeException (e) ;}finally {FD = null ;}}} private static void cypher (InputStream in, OutputStream out) throws Exception {int B =-1; while (B = in. read ())! =-1) {out. write (B ^ 0XFF) ;}} public static void main (String [] args) throws Exception {String srcPath = args [0]; // path of the source class file: String fileDir = args [1]; // FileInputStream (new FileInputStream (srcPath); String filename = srcPath. substring (srcPath. lastIndexOf ("\") + 1); String destPath = fileDir + "\" + filename; FileOutputStream fos = new FileOutputStream (destPath); cypher (FCM, fos ); fos. close (); FCM. 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 loader = 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);}}
An exception may occur when running the above Code:
Java. lang. ClassFormatError: Incompatible magic value 889275713 in class file cn/zq/demo/Data
Indicates that the class file is invalid,
If the result of running the above program is cn. zq. demo. Data-> My data!
Congratulations! Your program is ready to run. Your class loader runs successfully. Finally, you can download the project file, if you have any questions, please feel free to contact me.
Source Code address