import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; public class ClassLoaderTest extends ClassLoader { private String classLoaderName; private String fileExtension = ".class"; /** * 默认的情况下,自定义类的加载器会以SystemClassLoader为父类加载器,如果要改变这种机制,调第二种生成方法 */ public ClassLoaderTest(String classLoaderName) { super(); this.classLoaderName = classLoaderName; } public ClassLoaderTest(ClassLoader classLoader, String classLoaderName) { super(classLoader); this.classLoaderName = classLoaderName; } /** * 该方法会在底层调用 */ @Override protected Class<?> findClass(String className) throws ClassNotFoundException { byte[] data = this.loadClassData(className); return this.defineClass(className, data, 0, data.length); } // 在该示例里,不会执行该方法,也就是说,由于双亲委托机制,会由应用类加载器加载 // 如果加载的类,不在classpath里,意思就是应用类加载器加载不了,才会由此加载器加载 private byte[] loadClassData(String name) { byte[] data = null; InputStream is = null; ByteArrayOutputStream baos = null; try { this.classLoaderName = this.classLoaderName.replace(".", "/"); is = new FileInputStream(new File(name + this.fileExtension)); baos = new ByteArrayOutputStream(); int ch = 0; while (-1 != (ch = is.read())) { baos.write(ch); } data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { try { is.close(); baos.close(); } catch (Exception e) { e.printStackTrace(); } } return data; } public static void test(ClassLoader classLoader) throws Exception { Class<?> clazz = classLoader.loadClass("类名"); Object o = clazz.newInstance(); System.out.println(o); } public static void main(String[] args) throws Exception { ClassLoaderTest loader1 = new ClassLoaderTest("loader1"); test(loader1); } }
ps:同一个加载器的命名空间里,同一个类只能被加载一次
命名空间:由所有的父加载器和自己加载器组成的空间
只有由自定义类加载器的类才能被卸载