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