
正文
自定义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:同一个加载器的命名空间里,同一个类只能被加载一次
命名空间:由所有的父加载器和自己加载器组成的空间
只有由自定义类加载器的类才能被卸载





