Advanced Java Programming (11) ClassLoader class loader

1, ClassLoader class loader Introduction

  Provide a system in Java environment variables: ClassPath, the role of this property is mainly defined class loader path when JVM process starts, you can then be loaded in the class specify the path class loader in the JVM inside, that is, said class loader to find the means to find the source of the class.

System class loader

  If you say that now in order to get the class loader, then it must be to get through ClassLoader, and in order to get the object ClassLoader class, you must use the root of [reflected] class class implementation method: public ClassLoader getClassLoader (), when the acquired after the ClassLoader can also continue to acquire its parent class ClassLoader class object: public final ClassLoader getParent ();

· Example: observe the class loader

. 1  class the Message {
 2  }
 . 3  public  class JavaAPIDemo {
 . 4      public  static  void main (String [] args) {
 . 5          Class clazz the Message = <?>. Class ;
 . 6          System.out.println (clazz.getClassLoader ()); // Get the current class loader 
. 7          System.out.println (clazz.getClassLoader () getParent ().); // Get the parent class loader 
. 8          System.out.println (clazz.getClassLoader () getParent () getParent (.. )); // Get grandparent class loader 
9      }
 10  }
 11  / * 
12 jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
13 jdk.internal.loader.ClassLoaders$PlatformClassLoader@1e643faf
14 null
15  */

  From later versions and JDK1.10 JDK1.9 JDK1.8 [] [PlatformClassLoader] provided with a class loader, and in the previous versions and JDK1.8 loader is provided inside ExtClassLoader [], as installed in the JDK directory provides another ext directory, developers can [] * .jar files are copied to this directory, so it can be executed directly, but the development of such a treatment is not safe, the first time it was frowned upon, so from JDK1.9 be completely abolished, and in order, and between the system loader and application class loader to maintain a balance of design, provides the platform class loader.

  When you get a class loader can be implemented using a reflection-based processing load class loader.

2, custom processing ClassLoader

  Clearly the class loader function after, you can according to their need to implement a custom class loader, but must remember one thing: self-order custom class loader that loads in the last of all system class loader. System class loader for the class is loaded CLASSPATH find the path, and if they have self-defined class loader, can be assigned to any class by the developer loading position. 

① free to write a program class, and this class will be saved on disk;

 1 import java.io.*;
 2 
 3 public class MufasaClassLoader extends ClassLoader {
 4     private static final String MESSAGE_CLASS_PATH="D:"+ File.separator+"Message.class";
 5     /**
 6      * 进行指定类的加载
 7      * @param className 类的完整名称【包.类】
 8      * @return 返回一个指定类的class对象
 9      * @throws Exception 如果类文件不存在则无法加载
10      */
11     public Class<?> loadData(String className)throws Exception{
12         byte[] data=this.loadClassData();//读取二进制数据文件
13         if(data!=null){//读取到数据
14             return super.defineClass(className,data,0,data.length);
15         }
16         return null;
17 
18     }
19     private byte[] loadClassData()throws Exception{//通过文件进行类的加载
20         InputStream input=null;
21         ByteArrayOutputStream bos=null;//将数据加载到内存之中
22         byte[] data=null;
23         try{
24             bos=new ByteArrayOutputStream();//实例化内存流
25             input=new FileInputStream(new File(MESSAGE_CLASS_PATH));//文件流加载
26 //            byte[] data=new byte[1024];//进行读取方式①
27             input.transferTo(bos);//读取数据方式②
28             data= bos.toByteArray();//将所有读取到的字节数组取出
29         }catch (Exception e){
30 
31         }finally {
32             if(input!=null){
33                 input.close();
34             }
35             if(bos!=null){
36                 bos.close();
37             }
38         }
39         return data;
40     }
41 }

④编写测试类实现类加载控制;

 1 package cn.mufasa.demo;
 2 import cn.mufasa.util.MufasaClassLoader;
 3 import java.lang.reflect.Method;
 4 
 5 public class JavaAPIDemo1 {
 6     public static void main(String[] args) throws Exception {
 7         MufasaClassLoader classLoader=new MufasaClassLoader();
 8         Class<?> cls=classLoader.loadData("cn.mufasa.util.Message");//进行类的加载
 9         System.out.println(cls);
10         Object obj=cls.getDeclaredConstructor().newInstance();
11         Method method=cls.getDeclaredMethod("send");
12         method.invoke(obj);
13     }
14 }
15 /*
16 读取到数据
17 class cn.mufasa.util.Message
18 www.cnblogs.com
19  */

  如果在以后结合网络开发的话,就可以通过一个远程的服务器来确定类的功能。

 

⑤观察当前的Message类的加载器的情况

package cn.mufasa.demo;
import cn.mufasa.util.MufasaClassLoader;
import java.lang.reflect.Method;

public class JavaAPIDemo1 {
    public static void main(String[] args) throws Exception {
        MufasaClassLoader classLoader=new MufasaClassLoader();
        Class<?> cls=classLoader.loadData("cn.mufasa.util.Message");//进行类的加载
//        System.out.println(cls);
        System.out.println(cls.getClassLoader());//获取当前类的加载器
        System.out.println(cls.getClassLoader().getParent());//获取父类加载器
        System.out.println(cls.getClassLoader().getParent().getParent());//获取祖父类加载器


    }
}
/*
cn.mufasa.util.MufasaClassLoader@668bc3d5
jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
jdk.internal.loader.ClassLoaders$PlatformClassLoader@3fb6a447
 */

  如果说你先在定义了一个类,这个类的名称定义为:java.lang.String,并且利用了自定义类加载器进行加载处理,这个类将不会被加载,原因:Java之中针对于类加载器提供有双亲加载机制,如果现在要加载的类是由系统提供的类则会由系统类进行加载,如果现在开发者定义的类与系统类定义的名称相同,那么【为了保证系统的安全性】绝对不会加载。

Guess you like

Origin www.cnblogs.com/Mufasa/p/11184713.html