• 自定义ClassLoader的使用


     1 import java.io.ByteArrayOutputStream;
     2 import java.io.File;
     3 import java.io.FileInputStream;
     4 import java.io.InputStream;
     5 
     6 public class ClassLoaderTest extends ClassLoader {
     7 
     8     private String classLoaderName;
     9     private String fileExtension = ".class";
    10 
    11     /**
    12      * 默认的情况下,自定义类的加载器会以SystemClassLoader为父类加载器,如果要改变这种机制,调第二种生成方法
    13      */
    14 
    15     public ClassLoaderTest(String classLoaderName) {
    16         super();
    17         this.classLoaderName = classLoaderName;
    18     }
    19 
    20     public ClassLoaderTest(ClassLoader classLoader, String classLoaderName) {
    21         super(classLoader);
    22         this.classLoaderName = classLoaderName;
    23     }
    24 
    25     /**
    26      * 该方法会在底层调用
    27      */
    28     @Override
    29     protected Class<?> findClass(String className) throws ClassNotFoundException {
    30         byte[] data = this.loadClassData(className);
    31         return this.defineClass(className, data, 0, data.length);
    32     }
    33 
    34     // 在该示例里,不会执行该方法,也就是说,由于双亲委托机制,会由应用类加载器加载
    35     // 如果加载的类,不在classpath里,意思就是应用类加载器加载不了,才会由此加载器加载
    36     private byte[] loadClassData(String name) {
    37 
    38         byte[] data = null;
    39         InputStream is = null;
    40         ByteArrayOutputStream baos = null;
    41 
    42         try {
    43             this.classLoaderName = this.classLoaderName.replace(".", "/");
    44 
    45             is = new FileInputStream(new File(name + this.fileExtension));
    46             baos = new ByteArrayOutputStream();
    47 
    48             int ch = 0;
    49 
    50             while (-1 != (ch = is.read())) {
    51                 baos.write(ch);
    52             }
    53             data = baos.toByteArray();
    54 
    55         } catch (Exception e) {
    56             e.printStackTrace();
    57         } finally {
    58             try {
    59                 is.close();
    60                 baos.close();
    61             } catch (Exception e) {
    62                 e.printStackTrace();
    63             }
    64         }
    65 
    66         return data;
    67     }
    68 
    69     public static void test(ClassLoader classLoader) throws Exception {
    70         Class<?> clazz = classLoader.loadClass("类名");
    71         Object o = clazz.newInstance();
    72         System.out.println(o);
    73     }
    74 
    75     public static void main(String[] args) throws Exception {
    76         ClassLoaderTest loader1 = new ClassLoaderTest("loader1");
    77         test(loader1);
    78     }
    79 
    80 }
     

    ps:同一个加载器的命名空间里,同一个类只能被加载一次

    命名空间:由所有的父加载器和自己加载器组成的空间

    只有由自定义类加载器的类才能被卸载

  • 相关阅读:
    图解JavaScript原型和原型链
    hash数组快速查找一个字符串中出现最多的字符,并统计出现的次数
    JS中数组和字符串的方法大全
    用js实现排列组合
    js中一个对象当做参数传递时候?
    用JavaScript按一定格式解析出URL 串中所有的参数
    从Object.definedProperty中看vue的双向数据的绑定
    Uncaught (in promise) TypeError:的错误
    vue之生命周期的一点总结
    原子性和原子性操作
  • 原文地址:https://www.cnblogs.com/billmiao/p/9872212.html
Copyright © 2020-2023  润新知