快速业务通道

深入探讨Java类加载器 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-16
载器 ClassLoaderA 和 ClassLoaderB 分别读取了这个 Sample.class 文 件,并定义出两个 java.lang.Class 类的实例来表示这个类。这两个实例是不 相同的。对于 Java 虚拟机来说,它们是不同的类。试图对这两个类的对象进行 相互赋值,会抛出运行时异常 ClassCastException。下面通过示例来具体说明 。代码清单 3 中给出了 Java 类 com.example.Sample。

清单 3. com.example.Sample 类

package com.example; public class Sample {   private Sample instance;   public void setSample(Object instance) {      this.instance = (Sample) instance;   } }

深入探讨Java类加载器(4)

时间:2011-06-12 IBM 成富

如 代码清单 3 所示,com.example.Sample 类的方法 setSample 接受一个 java.lang.Object 类型的参数,并且会把该参数强制转换成 com.example.Sample 类型。测试 Java 类是否相同的代码如 代码清单 4 所示 。

清单 4. 测试 Java 类是否相同

public void  testClassIdentity() {   String classDataRootPath =  "C:\\workspace\\Classloader\\classData";    FileSystemClassLoader fscl1 = new FileSystemClassLoader (classDataRootPath);   FileSystemClassLoader fscl2 = new  FileSystemClassLoader(classDataRootPath);   String className  = "com.example.Sample";   try {     Class<?>  class1 = fscl1.loadClass(className);     Object obj1 =  class1.newInstance();     Class<?> class2 =  fscl2.loadClass(className);     Object obj2 =  class2.newInstance();     Method setSampleMethod =  class1.getMethod("setSample", java.lang.Object.class);      setSampleMethod.invoke(obj1, obj2);   } catch (Exception e)  {     e.printStackTrace();   } }

代码清单 4 中使用了类 FileSystemClassLoader 的两个不同实例来分别加载类 com.example.Sample,得到了两个不同的 java.lang.Class 的实例,接着通过 newInstance() 方法分别生成了两个类的对象 obj1 和 obj2,最后通过 Java 的反射 API 在对象 obj1 上调用方法 setSample,试图把对象 obj2 赋值给 obj1 内部的 instance 对象。代码清单 4 的运行结果如 代码清单 5 所示。

清单 5. 测试 Java 类是否相同的运行结果

java.lang.reflect.InvocationTargetException   at  sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at  sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39)  at  sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)  at  java.lang.reflect.Method.invoke(Method.java:597)  at  classloader.ClassIdentity.testClassIdentity(ClassIdentity.java:26)  at classloader.ClassIdentity.main(ClassIdentity.java:9) Caused by: java.lang.ClassCastException: com.example.Sample    cannot be cast to com.example.Sample   at  com.example.Sample.setSample(Sample.java:7)  ... 6  more

从 代码清单 5 给出的运行结果可以看到,运行时抛出了 java.lang.ClassCastException 异常。虽然两个对象 obj1 和 obj2 的类的名 字相同,但是这两个类是由不同的类加载器实例来加载的,因此不被 Java 虚拟 机认为是相同的。

了解了这一点之后,就可以理解代理模式的设计动机 了。代理模式是为了保证 Java 核心库的类型安全。所有 Java 应用都

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号