Java虚拟机类型卸载和类型更新解析 - 编程入门网
最好能自己调试一下).
【测试场景五】同一个类加载器实例重复加载同一类型 说明:首先要对已有的用户自定义类加载器做一定的修改,要覆盖已有的类加载逻辑,MyURLClassLoader.java类简要修改如下:重新运行测试场景四中的测试代码 1 public class MyURLClassLoader extends URLClassLoader { 2 //省略部分的代码和前面相同,只是新增如下覆盖方法 3 /* 4 * 覆盖默认的加载逻辑,如果是D:/classes/下的类型每次强制重新完整加载 5 * 6 * @see java.lang.ClassLoader#loadClass(java.lang.String) 7 */ 8 @Override 9 public Class<?> loadClass(String name) throws ClassNotFoundException {10 try {11 //首先调用系统类加载器加载12 Class c = ClassLoader.getSystemClassLoader().loadClass(name);13 return c;14 } catch (ClassNotFoundException e) {15 // 如果系统类加载器及其父类加载器加载不上,则调用自身逻辑来加载D:/classes/下的类型16 return this.findClass(name);17 }18 }19 } Java虚拟机类型卸载和类型更新解析(5)时间:2011-01-03 zhuxing说明: this.findClass(name)会进一步调用父类URLClassLoader中的对应方法,其中涉及到了defineClass(String name)的调用,所以说现在类加载器MyURLClassLoader会针对D:/classes/目录下的类型进行真正意义上的强制加载并定义对应的类型信息. 测试输出如下: Exception in thread "main" java.lang.LinkageError: duplicate class definition: MyClass at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at MyURLClassLoader.loadClass(MyURLClassLoader.java:51) at Main.main(Main.java:27) 结论:如果同一个类加载器实例重复强制加载(含有定义类型defineClass动作)相同类型,会引起java.lang.LinkageError: duplicate class definition. 【测试场景六】同一个加载器类型的不同实例重复加载同一类型 1 public class Main { 2 public static void main(String[] args) { 3 try { 4 MyURLClassLoader classLoader1 = new MyURLClassLoader(); 5 Class classLoaded1 = classLoader1.loadClass("MyClass"); 6 MyURLClassLoader classLoader2 = new MyURLClassLoader(); 7 Class classLoaded2 = classLoader2.loadClass("MyClass"); 8 9 //判断两个Class实例是否相同10 System.out.println(classLoaded1 == classLoaded2);11 } catch (Exception e) {12 e.printStackTrace();13 }14 }15 } 测试对应的输出如下: false 【类型更新总结】 由不同类加载器实例重复强制加载(含有定义类型defineClass动作)同一类型不会引起java.lang.LinkageError错误,但是加载结果对应的Class类型实例是不同的,即实际上是不同的类型(虽然包名+类名相同). 如果强制转化使用,会引起ClassCastException.(说明: 头一段时间那篇文章中解释过,为什么不同类加载器 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |