Probe into the mystery of the Java class loading mechanism

xiaoxiao2021-03-06  43

First, after jdk1.2, class load is done by delegation, which means if ClassLoader can't find classes, it will ask the parent ClassLoader to perform this task, all ClassLoaders's roots are system ClassLoader, which will be lacking Provincial Mode Loading class - that is, from the local file system. Today we will discuss how these mechanisms are running in JVM. Let us assume that there is a class byte code file (such as a hello.class file), how is he loaded in the application, and form a class object? The purpose of this article is to explain this problem. There is a ClassLoader class in the java.lang package, and the basic goal of ClassLoader is to serve the request for classes. When the JVM needs to use classes, it requests this class based on the name, and then ClassLoader tries to return a class object that represents this class. Customized ClassLoader can be created by covering a different phase of this process. There is a loadclass (String Name, Boolean Resolve) method, which is the entry point of ClassLoader. After jdk1.2, the loadClass method calls the FindClass method by default. Details can refer to the API document, and the ClassLoader we write is mainly for Overwrites two methods. Go back to the question we just, how to read the bytecode file, and make it a class object? There is a method in ClassLoader, Class DefineClass (String Name, Byte [] B, INT OFF, INT LEN), the answer is here, and we read the Class byte file (such as hello.class) one byte In the array, byte [] b, translate it into a Class object, and these data can be derived from files, networks, etc., magic :) DefineClass management JVM's complex, mysterious and reliance on the implementation - it The code is analyzed into runtime data structures, check validity, and more. Don't worry, you don't have to write it yourself. In fact, even if you want to do this, you can't overwrite it because it has been marked into the end. Other methods: FindsystemClass method: Load files from the local file system. It looks for class files in the local file system. If there is, use defineClass to convert the original byte into a Class object to convert the file into classes. FindClass method: JDK1.2 After the default implementation of LoadClass, this new method is called. The use of FindClass contains all special code of your ClassLoader without having to copy other code (for example, when a special method fails, calling the system classloader). GetSystemClassLoader: If you override FindClass or LoadClass, GetSystemClassLoad allows you to access system ClassLoader with actual ClassLoader objects (rather than fixed from FindsystemClass call it). GetParent: In order to delegate the class request to the parent ClassLoader, this new method allows ClassLoader to get its parent ClassLoader. This method can be used when using a special method, custom ClassLoader cannot find classes.

ResolVeclass: It is possible to load classes in an incomplete (without parsing) or to complete (with parsing). When writing our own loadClass, resolveclass can be called, depending on the value of the LoadClass's Resolve parameter. FindloadedClass: Acting as a cache, when requesting loadClass to load classes, it calls this method to see if ClassLoad has been loaded, which avoids the trouble of reloading existing classes. This method should be called first. Second, workflow: 1) Call FindloadedClass (String) to see if there is a class that has been loaded, if not, then use the special magic way to get the original byte. 2) Call the LoadClass method through the parent classLacer, if the parent class classloader is NULL, then load the class by default, that is, the system ClassLoader. 3) Call FindClass (String) to find classes and get classes; 4) If the value of loadclass's Resolve parameter is true, then call resolveclass to parse the Class object. 5) If there is no class, return to ClassNotFoundException. 6) Otherwise, return the class to the call. Third, an example in which ClassLoader is implemented:

/***CompilingClassLoader.java*Copyright 2005-2-12 * / import java.io *;. Public class CompilingClassLoader extends ClassLoader {// read the contents of a document private byte [] getBytes (String filename) throws IOException {File File = new file (filename); long len = file.length (); byte [] RAW = new byte [(int) LEN); fileinputstream fin = new fileInputstream (file); int R = fin.read (RAW); IF (r! = len) throw new oException ("Can't Read All," R "! =" LEN); Fin.Close (); Return Raw;} Private Boolean Compile (String Javafile) throws oews oews ooException {system .out.println ("ccl: compiling" javafile "..."); // call the system's javac command process p = runtime.Getruntime (). EXEC ("Javac" javafail; try {// other thread Waiting for this thread to complete the P.WaitFor ();} catch (interruptedException IE {system.out.println (} int RET = p.exitvalue (); return Ret == 0;} public class loadclass (String name , boolean resovle) throws ClassNotFoundException {Class clas = null; clas = findLoadedClass (name); // packet described here indicates String fileStub = name.replace (, '/') '.';. String javaFilename = fileStub "java "; String ClassFileName = filestu B ". Class"; file javafile = new file (javaFileName); file classfile = new file (classfilename); // If there is a Class file, it is not compiling if (javafile.exists () && (! ClassFile.exists () || javaFile.lastModified ()> classFile.lastModified ())) {try {if (compile (javaFilename) || classFile.exists ()) {throw new ClassNotFoundException ( "ClassNotFoundExcetpion:"!! javaFilename);}} catch (IOException IE) {throw new classnotfoundexception (IE.toString ());}} Try {byte [] RAW = getBytes (ClassFileName); // constructs a class structure by reading data, this is the core Clas = DefineClass (Name, RAW , 0, Raw.Length;

} Catch (IOException IE) {//} if (clas == null) {class = findsystemclass (name);} system.out.println ("FindsystemClass:" CLAS); if (resovle && clas! = null) { ResolVeclass (CLAS);} if (Clas == Null) {throw new classnotfoundexception (name);} Return Clas;}} test This loader: / *** Testrun.java * Copyright 2005-2-11 * / Import Java. lang.reflect *;. public class TestRun {public static void main (String [] args) throws Exception {String progClass = args [0]; String progArgs [] = new String [args.length-1]; System.arraycopy ( args, 1, progArgs, 0, progArgs.length); CompilingClassLoader ccl = new CompilingClassLoader (); class clas = ccl.loadClass (progClass); // returns a class type class of [] mainArgType = {(new String [0] ) .getClass ()}; method main = clas.getMethod ("main", maingtype); object argsArray [] = {progargs}; main.invoke (null, argsarray);}} The core content of the above has been written, compile After we get two files: compilingclassloader.class, testrun.class four, write an example, then run our classloader / *** hello.java * / public class hello {public static void main (string [] args) { IF (args.length! = 1) {sys Tem.err.Println ("Error, Exit!"); System.exit (1);} String name = args [0]; system.out.println ("Hello," Name);}} Ok, run Java Testrun Hello

............ Hello, A Fei

转载请注明原文地址:https://www.9cbs.com/read-57868.html

New Post(0)