java class loading mechanism

    Each class will be in a corresponding java Class object, we usually call this Class object bytecode object, then the bytecode object is who is going to produce it? The java class is loaded into memory by whom it? Next, I introduce is responsible for loading java bytecode file into memory, to create a Class object class ClassLoader, which is in the java class loader.

    Class loader is generally provided by the system, we do not need to implement their own, but through our custom class loader can be more flexible loading class files. There are three default class loader are the Bootstrap ClassLoader (Start class loader) in java, Extension ClassLoader (extension class loader), Application ClassLoader (application class loader), in which the boot class loader is responsible for basic load of java class, extended class loader is responsible for loading about the expansion of java classes, application class loader is responsible for loading the application class is specified in the class path class. This class loader has three parent-child relationship, which is the parent Application ClassLoader Extension ClassLoader, Extension ClassLoader parent is Bootstrap ClassLoader. But they are not the inheritance of the father and son relationship but appointed his son, there is a parent variable points Extension ClassLoader in Application ClassLoader, the Extension ClassLoader also has a parent variable points Bootstrap ClassLoader. When a class is loaded it will first determine whether the class is loaded too, if the class is already loaded over a Class object will return, if not over-loaded will let the parent if the parent loader to load loader load successfully returned directly Class object, if the parent does not load successfully loaded before trying to load your own. This class loading process is generally what we call "parents delegate" mode. java classes loaded in this way has been adopted in order to prevent repeated loading class, preventing the type of the original user-defined type covered java.

    Understand the class loading mechanism in java we want to introduce today the focus of the class: ClassLoader. ClassLoader class is an abstract class, each object has a Class getClassLoader () method to get ClassLoader. ClassLoaer class has a getParent () method to get the parent ClassLoader loader.

public class TestClassLoader {
    public static void main(String[] args) {
         ClassLoader classLoader = TestClassLoader.class.getClassLoader();
         while(classLoader!=null){
             System.out.println(classLoader.getClass().getName());
             classLoader = classLoader.getParent();
         }
         System.out.println(String.class.getClassLoader()); 
         
         
    }
}

输出:
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
null

It should be noted that the Bootstrap ClassLoader is written in C ++ so the final output returns null. ClassLoader there in a static method returns system default class loader getSystemClassLoader. ClassLoader There is also an important method loadClass (String name) used to load classes.

public class TestClassLoader {
    public static void main(String[] args) throws ClassNotFoundException {
         ClassLoader classLoader = ClassLoader.getSystemClassLoader();
         Class cls = classLoader.loadClass("com.reflect.generic.TestClassLoader");
         System.out.println(cls.getClassLoader().getClass().getName());
    }
}

I should explain, when I learned to study the reflection of the static method forName Class class can also load the class, today we ClassLoader loadClass method of introduction can also load the class, but both of them are different, the use of Class forName method will load the class initialization class but use the loadClass method does not initialize class.

    Java class loading mechanism is to allow user-defined class loader. Custom class loader can achieve a lot of powerful features such as hot-deploy technology and web applications without isolation. In java custom class loader to be not so difficult to imagine. We only need to inherit ClassLoader class and then override the method can findClass inside. findClass we write primarily how to find the class file byte form by their own logic and then call defineClass (String name, byte [] b, int off, int len) where name is the class name, b word is stored bytecode section arrays, off the starting position, len is the length.

public class MyClassLoader extends ClassLoader {
    
    private String path;
    
    public MyClassLoader(String path){
         this.path = path;
    }
    
    
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] b = getClassByte(name,this.path);
        return defineClass(name, b, 0, b.length);
        
    }
    
    private static byte[] getClassByte(String name,String path){
        String classPath = name.replace(".","/");
        String fileName = path+classPath + ".class";
        BufferedInputStream ins = null;
        ByteArrayOutputStream os =null;
        try {
            ins = new BufferedInputStream(new FileInputStream(new File(fileName)));
            os = new ByteArrayOutputStream();
            int i =0;
            while((i=ins.read())!=-1){
                os.write(i);
                
            }        
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(ins!=null){
                try {
                    ins.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return os.toByteArray();
    }


    public String getPath() {
        return path;
    }


    public void setPath(String path) {
        this.path = path;
    }
  
}

In the time of the call:

public class TestClassLoader {
    public static void main(String[] args) throws ClassNotFoundException {
        MyClassLoader myclassLoader = new MyClassLoader("E:\\react\\testclassloader\\");
        Class cls = myclassLoader.findClass("com.reflect.generic.User");
        System.out.println(cls.getClassLoader().getClass().getName());
    }
}

输出:
com.reflect.generic.MyClassLoader

It should explain the different classes loaded with a class Class object acquired is different. For each ClassLoader of the same class can only be loaded once.

Guess you like

Origin www.cnblogs.com/suyang-java/p/10987891.html