1.类加载器双亲委派机制实例
package com.test.classloader;
public class TestBean {
public TestBean() {}
}
package com.test.classloader;
public class ClassLoaderTest {
public static void main(String[] args) {
try {
//调用加载当前类的类加载器(这里即为系统类加载器)加载TestBean
Class typeLoaded = Class.forName("com.test.classloader.TestBean");
//查看被加载的TestBean类型是被那个类加载器加载的
System.out.println(typeLoaded.getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果是:sun.misc.Launcher$AppClassLoader@6d4b473
将当前工程输出目录下的…/classloader/test/bean/TestBean.class打包进test.jar剪贴到< Java_Runtime_Home >/lib/ext目录下(现在工程输出目录下和JRE扩展目录下都有待加载类型的class文件)。再运行测试一测试代码,结果:sun.misc.Launcher$ExtClassLoader@7259da
对比我们明显可以验证前面说的双亲委派机制,系统类加载器在接到加载classloader.test.bean.TestBean类型的请求时,首先将请求委派给父类加载器(标准扩展类加载器),标准扩展类加载器抢先完成了加载请求。
将test.jar拷贝一份到< Java_Runtime_Home >/lib下,运行测试代码,输出:sun.misc.Launcher$ExtClassLoader@7259da
测试三和测试二输出结果一致。那就是说,放置到< Java_Runtime_Home >/lib目录下的TestBean对应的class字节码并没有被加载,这其实和前面讲的双亲委派机制并不矛盾。虚拟机出于安全等因素考虑,不会加载< Java_Runtime_Home >/lib存在的陌生类,开发者通过将要加载的非JDK自身的类放置到此目录下期待启动类加载器加载是不可能的
2.加载远程加载器上的class:
URL jarUrl = new URL("file://localhost//***.jar");
URL[] urls = new URL[] { jarUrl };
URLClassLoader cl = new URLClassLoader(urls);
Class classzz = cl.loadClass("com.test.platform.api.IHelloService");
参考:点击打开链接