快速业务通道

Java虚拟机类型卸载和类型更新解析 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-21
最好能自己调试一下).

【测试场景五】同一个类加载器实例重复加载同一类型

说明:首先要对已有的用户自定义类加载器做一定的修改,要覆盖已有的类加载逻辑,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 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号