`
jaychang
  • 浏览: 741950 次
  • 性别: Icon_minigender_1
  • 来自: 嘉兴
社区版块
存档分类
最新评论

不同类装载器生成的Class对象,所生成的实例相互转化报ClassCastException

 
阅读更多
package com.jaychang.demo;

public class Dog {
	public String say(String name) {
		System.out.println("Hello " + name);
		return "Hello " + name;
	}
}

 

package com.jaychang.demo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ClassLoaderTest {
	static class MyClassLoader extends ClassLoader {
		public Class<?> getClass(byte[] byteArray, int off, int len) {
			return super.defineClass(byteArray, off, len);
		}
	}

	public static void main(String[] args) {
		MyClassLoader myClassLoader = new MyClassLoader();
		File classFile = new File(
				"F:/Workspace/classloader-demo/target/classes/com/jaychang/demo/Dog.class");
		ByteArrayOutputStream baos = null;
		BufferedOutputStream bos = null;
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		try {
			fis = new FileInputStream(classFile);
			baos = new ByteArrayOutputStream();
			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(baos);
			byte[] buff = new byte[1024];
			int len = -1;
			while ((len = bis.read(buff, 0, 1024)) != -1) {
				bos.write(buff, 0, len);
			}
			bos.flush();
			byte[] byteArray = baos.toByteArray();
			Class clazz1 = myClassLoader.getClass(byteArray, 0,
					byteArray.length);
			Class clazz2 = Class.forName("com.haipicheng.dubbo_demo.Dog");
			Class clazz3 = Dog.class;
			System.out.println("clazz1类装载器为" + clazz1.getClassLoader()
					+ ",clazz2类装载器为" + clazz2.getClassLoader() + ",clazz3类装载器为"
					+ clazz3.getClassLoader());
			System.out.println("clazz1 == clazz2 ?" + (clazz1 == clazz2));
			System.out.println("clazz2 == clazz3 ?" + (clazz2 == clazz3));
			System.out.println("clazz1 == clazz3 ?" + (clazz1 == clazz3));

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (null != fis) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (null != bis) {
				try {
					bis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (null != baos) {
				try {
					baos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (null != bos) {
				try {
					bos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
} 

com.jaychang.demo.Dog,com.jaychang.demo.Dog,com.jaychang.demo.Dog

clazz1类装载器为com.jaychang.demo.ClassLoaderTest$MyClassLoader@97d01f,clazz2类装载器为sun.misc.Launcher$AppClassLoader@472d48,clazz3类装载器为sun.misc.Launcher$AppClassLoader@472d48

clazz1 == clazz2 ?false

clazz2 == clazz3 ?true

clazz1 == clazz3 ?false

 

说明不同类装载器加载生成的Class对象,尽管调用getName得到的全限定名称是一一样的,但是他们是不同类装载器装载的,由Class对象生成对应的实例就不能相互转换,就会报ClassCastException了

分享到:
评论

相关推荐

    JBoss管理与开发

    这通常发生在不同类装载器装载的类试图相互访问对方的私有成员时。 #### 五、结论 通过对JBoss JMX实现架构和类装载器机制的深入分析,我们可以更好地理解JBoss是如何管理和监控其内部资源和服务的。正确理解和...

    第七课 对象类型及相互转化.rar

    在Java编程语言中,对象类型和相互转化是核心概念,特别是在面向对象编程中。本课主要探讨了如何创建和操作不同类型的对象,以及如何在不同类型之间进行转换。下面将详细阐述这些关键知识点。 1. **对象类型**: ...

    java类加载器

    在JVM中,每个类都有一个唯一的标识,由其完全限定类名(包括包名和类名)以及加载它的类加载器实例决定。这意味着,即使两个类具有相同的完全限定名,如果由不同的类加载器加载,它们也会被视为不同的类,无法相互...

    ClassCastException解决办法.md

    在转换对象之前,应该使用`instanceof`操作符来验证目标对象是否为某个类的实例或者是其子类的实例。正确的代码示例应该如下: ```java if(object instanceof TargetClass){ TargetClass target = (TargetClass) ...

    Java类加载内幕.pdf

    判断“同一个类”通常基于完全限定类名(包括包名和类名),但在JVM内部,类的唯一标识还包括加载它的类加载器实例。这意味着,即使完全相同的类名,如果由不同的类加载器加载,也会被视为不同的类,无法相互兼容。 ...

    java.lang.ClassCastException(解决方案).md

    在Java编程过程中,类转换异常(java.lang.ClassCastException)是一种常见的异常,当程序试图将一个对象强制转换为不兼容的类型时,就会抛出此类异常。本文将详细介绍如何解决java.lang.ClassCastException,包括...

    weblogic解决clob添加失败 classcastexception

    然而,当WebLogic在处理CLOB对象时,如果数据源配置不当或者代码处理方式有误,就可能出现ClassCastException。 首先,我们需要了解ClassCastException的原因。这个异常通常发生在试图将一个对象强制转换为不兼容...

    ClassCastException如何解决.md

    通过设计模式,例如使用接口或抽象类代替具体类的使用,以及运用多态来处理不同类型的对象,可以有效地避免直接的类型转换。这通常意味着需要对现有代码结构进行较大幅度的调整,但这种重构有助于提升长期的代码质量...

    JBoss管理与开发核心技术_第三版电子书

    例如,在不同的`URLClassLoader`装载相同的JAR文件时,尽管从字节码角度看这些类是相同的,但由于它们被不同的类装载器装载,因此被视为不同的类型。这可能导致`ClassCastException`异常。 ### 总结 通过对JBoss ...

    java范例开发大全

    实例38 强制类型转换异常(ClassCastException) 56 实例39 索引越界异常(IndexOutOfBoundsException) 57 实例40 空指针异常(NullPointerException) 58 实例41 数字格式转换异常(NumberFornatException) 59 ...

    ClassCastException(解决方案).md

    为了解决这一问题,推荐的方法是在进行类型转换前使用instanceof关键字检查对象是否为预期的类或其子类的实例。如果对象不符合条件,则应该避免转换操作,或提供相应的错误处理逻辑,比如输出提示信息。这样就可以在...

    Java范例开发大全 (源程序)

     实例38 强制类型转换异常(ClassCastException) 56  实例39 索引越界异常(IndexOutOfBoundsException) 57  实例40 空指针异常(NullPointerException) 58  实例41 数字格式转换异常...

    Java_ClassLoader详解

    每个 `.class` 文件都会被特定的类加载器实例加载到 JVM 中,并形成对应的 `Class` 对象。不同类加载器加载同一个类的 `.class` 文件时,这些类虽然名称相同但被认为是不同的类型。这意味着即使两个类具有相同的完全...

    java.lang.ClassCastException

    在Java编程中,`java.lang.ClassCastException`是一个运行时异常,通常发生在强制类型转换时,如果尝试将一个对象转换为其非兼容类型时就会抛出。这个异常表明在编译时可能成功的类型转换,在运行时被证明是错误的。...

    final修饰符与类型转化

    在Java编程中,`final`修饰符和类型转化是两个重要的概念,它们分别涉及类的继承限制和对象的类型转换。 1. `final`修饰符: - `final`类:当一个类被声明为`final`时,它无法被其他类继承。这通常用于防止他人...

    day08面向对象-内部类、异常.doc

    根据内部类的定义位置不同,我们可以将其分为成员内部类(Member Inner Class)和局部内部类(Local Inner Class)。 #### 成员内部类 成员内部类是定义在外部类成员位置上的内部类。它可以被声明为`public`、`...

Global site tag (gtag.js) - Google Analytics