Java高级进阶:自定义ClassLoader

假如我们的类不在classpath下,而我们又想读取一个自定义的目录下的class,如果做呢?

读取自定义目录的类

示例读取c:/test/com/test.jdk/Key.class这个类。

1
2
3
4
5
package com.test.jdk;

public class Key {
   private String key = "111111";
}

自定义ClassLoader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import org.apache.commons.io.IOUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class LocalClassLoader extends ClassLoader {

   private String path = "c:/test/";

   @Override
   protected Class<?> findClass(String name) throws ClassNotFoundException {
       Class<?> cls = findLoadedClass(name);
       if (cls != null) {
           return cls;
       }

       if (!name.endsWith(".Key")) {
           return super.loadClass(name);
       }

       try {
           InputStream is = new FileInputStream(path + name.replace(".", "/") + ".class");
           byte[] bytes = IOUtils.toByteArray(is);
           return defineClass(name, bytes, 0, bytes.length);
       } catch (IOException e) {
           e.printStackTrace();
       }

       return super.loadClass(name);
   }
}

开始读取类

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
   try {
       LocalClassLoader lcl = new LocalClassLoader();
       Class<?> cls = lcl.loadClass("com.test.jdk.Key");
       Field field = FieldUtils.getField(cls, "key", true);
       Object value = field.get(cls.newInstance());
       System.out.println(value);
   } catch (Exception e) {
       e.printStackTrace();
   }
}

自定义类加载器正常加载到类,程序最后输出:111111

URLClassLoader

上面自定义一个类加载器来读取自定义的目录,其实可以直接使用URLClassLoader就能读取,它已经实现了路径下类的读取逻辑。

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
   try {
       URLClassLoader ucl = new URLClassLoader(new URL[]{new URL("c:/test/")});
       Class<?> cls = ucl.loadClass("com.test.jdk.Key");
       Field field = FieldUtils.getField(cls, "key", true);
       Object value = field.get(cls.newInstance());
       System.out.println(value);
   } catch (Exception e) {
       e.printStackTrace();
   }
}


发布于 2020-04-01 21:08:39
分享
海报
177
上一篇:HTML5应用程序缓存Application Cache详解下一篇:关于Java序列化你应该知道的一切
目录

    忘记密码?

    图形验证码