【参考资料】
分析AppClassLoader,ExtClassLoader和URLClassLoader的关系http://blog.csdn.net/irelandken/article/details/7046689
在自定义类加载器中,我们自定义了一个CustomClassLoader用于从D:\temp目录下读取.class文件
但是实际上JDK已经给我们提供了URLClassLoader用于从URL路径中读取,可以直接拿来使用。
之前在讲内置类加载器中讲过:
其实可以简单的理解为,这些类加载器的处理逻辑都是相同的,读取.class字节码文件生成Class类,只不过是从不同的路径读取。
其实也是因为,AppClassLoader、ExtClassLoader其实就是从URLClassLoader继承的。(上图中子类看不到这两个类,是因为这两个类并未在JDK中提供)
但是需要注意,虽然继承关系是AppClassLoader继承自URLClassLoader,但是父类委托关系依然是URLClassLoader位于最底端。(应该是AppClassLoader重新设置了parent)
Java Code
| package com.bjsxt.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class Test { public static void main(String[] args) throws IOException { try { URL[] urls=new URL[]{new URL("file://D:/temp/")}; ClassLoader loader=new URLClassLoader(urls); Class<?> clazz = loader.loadClass("com.bjsxt.test.HelloLoader"); Method declaredMethod = clazz.getDeclaredMethod("sayLoader", null); declaredMethod.invoke(null, null); //输出自定义类加载器的父类委托关系 while(loader!=null){ System.out.println(loader); loader=loader.getParent(); } //输出AppClassLoader的继承关系 ClassLoader appClassLoader = Test.class.getClassLoader(); clazz = appClassLoader.getClass(); while(clazz.getSuperclass()!=null){ System.out.println(clazz.getSuperclass()); clazz=clazz.getSuperclass();//反射获取父类类型 } } catch (MalformedURLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } |