`
chillwarmoon
  • 浏览: 155043 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ClassLoader对类的级联加载

    博客分类:
  • JVM
F# 
阅读更多
转载请注明来自:http://chillwarmoon.iteye.com
在一个ClassLoader实例中,如果加载某个Class,那么被加载的Class是属于该ClassLoader所定义的namespace之内的。表现为不同的classloader实例虽然加载的Class完全相同,但是不能够相互类型转化,而且不能够通过类型转换成其他classloader加载的类。
但是在自定义的CustomClassLoader中,(1)Test test=(Test)clazz.newInstance()的类型转换是成功的,而且转换的是SystemClassLoader所加载的Test.class;(2)TestSub test2=(TestSub)clazz.newInstance()的类型转换是失败的。
这是为什么呢?
public class CustomClassLoader extends ClassLoader{
	public Class load(String arg){
		return getClass(arg);
	}
	
	public Class getClass(String arg){
		String path=System.getProperty("user.dir");
		String fullPath=path+"/bin/"+arg.replace(".", File.separator)+".class";
		byte[] classCode=null;
		File f=new File(fullPath);
		if(f.exists()){
			try {
				FileInputStream fis=new FileInputStream(f);
				classCode=new byte[fis.available()];
				fis.read(classCode);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return defineClass(arg,classCode, 0, classCode.length);
		}
		try {
			return findSystemClass(arg);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static void main(String args[]){
		Class clazz=new CustomClassLoader().load("com.hzb.classloader.TestSub");
		try {
			Test test=(Test)clazz.newInstance();
			TestSub test2=(TestSub)clazz.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		
	}

}

答案就在于CustomClassLoader并未覆盖父类的loadClass方法,在该例子中,虽然是通过CustomClassLoader.load方法,来调用defineClass方法加载class,但是该defineClass方法仍然需要调用ClassLoader.loadClass方法来级联加载与之相关的类,包含其父类,接口。因此该例子中仅仅是对字节码文件TestSub.class进行了load,而Test仍然是由SystemClassLoader所加载,因此会出现Test test=(Test)clazz.newInstance()成功执行,而TestSub test2=(TestSub)clazz.newInstance()执行失败的情况。

如果将CustomClassLoader.load方法名称改变为loadClass,则在调用defineClass时会加载Test.class到该classLoader实例,此时再次调用Test test=(Test)clazz.newInstance()会产生类型转换失败的错误。

PS:在调用clazz.newInstance方法时,会使用classLoader的loadClass方法,来加载类的关联类。因此不同的classLoader都有着自己的namespace。
分享到:
评论

相关推荐

    JAVA ClassLoader 讲解 (类加载器)

    * 对类文件范式有一定的了解。 #### 三、类加载器结构 类加载器在Java中遵循一个层次化的结构。Java的类加载器体系结构由三个主要类型的类加载器组成: 1. **引导类加载器(Bootstrap ClassLoader)**:这是最基础...

    ClassLoader类加载机制和原理详解

    双亲委派模型使得系统类(如java.*开头的类)由Bootstrap ClassLoader加载,而用户自定义类由应用程序类加载器(AppClassLoader)加载。这避免了类的冲突,保持了系统类库的稳定性。但有时我们可能需要打破这种模型...

    ClassLoader类加载器

    在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。了解和掌握ClassLoader的工作原理以及如何自定义ClassLoader对于深入理解Java应用程序的运行机制非常有帮助。以下是对...

    ClassLoader(类加载机制)1

    Bootstrap ClassLoader负责加载JDK的核心库,Extension ClassLoader加载Java的扩展库,而App ClassLoader则加载应用的类路径下的类。用户还可以自定义类加载器,用于加载特定位置或格式的类。 2. **Java类** Java...

    java的ClassLoader类加载器机制

    在 JVM 运行过程中,类加载器会形成一个层次结构,包括引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader)。 引导类加载器(Bootstrap ...

    【图解版】深入分析ClassLoader类加载工作机制

    【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!

    classloader类加载器_基于java类的加载方式详解

    扩展类加载器是一个Java类,它在运行时被Bootstrap ClassLoader加载,并且它同样会加载扩展API中的类。 3. Application ClassLoader(应用程序类加载器):也被称为System ClassLoader(系统类加载器),它负责加载...

    tomcat 类加载机制 —— ClassLoader

    《Tomcat类加载机制——ClassLoader详解》 在Java Web开发中,Tomcat作为最常用的Servlet容器,其类加载机制对于理解和优化应用性能至关重要。本文将深入探讨Tomcat的ClassLoader是如何工作的,以及它如何影响到...

    ClassLoader类加载机制

    类加载器是 Java 语言的一个创新,也是 ...不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试 ClassNotFoundException和 NoClassDefFoundError等异常。

    使用classloader动态加载Class

    因此,在实现动态加载时,需要对加载的类进行严格的权限控制和安全检查,防止恶意代码的注入。 6. **异常处理**:在处理类加载时,可能会遇到如ClassNotFoundException等异常,这时需要适当地捕获并处理这些异常,...

    探究java的ClassLoader及类变量初始化顺序

    在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作机制以及类变量初始化的顺序对于深入理解Java运行时环境至关重要。这篇博文将探讨这两个主题。 首先,让...

    Java中ClassLoader类加载学习总结

    Java中ClassLoader类加载学习总结 ClassLoader类加载是Java语言的一种创新,目的是为了将类的加载过程与虚拟机解耦,达到”通过类的全限定名来获取描述此类的二进制字节流“的目的。类加载器的基本模型就是双亲委派...

    Java类加载器(ClassLoader)1

    Java类加载器分为三种主要类型:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader,也称为系统类加载器)。它们共同工作,确保了Java...

    S18-ClassLoader类加载流程1

    - **应用程序类加载器(Application ClassLoader)**:也称为系统类加载器,负责加载用户类路径(classpath)上的类库。 类加载器之间并非继承关系,而是通过委托关系实现。例如,AppClassLoader会委托...

    ClassLoader 详解.doc

    深入理解ClassLoader的工作原理对于优化应用性能、解决类加载问题以及实现自定义加载策略至关重要。 首先,JVM启动时,会构建一个类加载器的层次结构,主要包括三个基本类加载器: 1. Bootstrap ClassLoader:引导...

    java应用程序类加载器,ClassLoader for java Application

    1. **引导类加载器(Bootstrap ClassLoader)**:这是最基础的类加载器,由JVM本身实现,主要负责加载JDK核心库,如rt.jar中的类,这些类通常位于JRE的lib目录下。 2. **扩展类加载器(Extension ClassLoader)**:由...

    ClassLoader动态加载dex

    在Android系统中,ClassLoader是Java类加载器...这涉及到对Android的类加载机制、DexFile API以及可能的类冲突解决策略的深入理解。通过自定义ClassLoader并结合相应的源代码,我们可以构建出灵活、可扩展的应用架构。

    java类加载器-tomcat中的类加载器

    2. Webapp ClassLoader:每个Web应用程序都有自己的Webapp ClassLoader,用于加载WEB-INF/classes和WEB-INF/lib下的类,遵循"父子优先"原则,优先尝试从父类加载器加载,如果找不到再从自身加载。 3. Shared ...

    ClassLoader

    通过对`ClassLoader`的基本概念、工作原理、双亲委托机制以及不同类型的类加载器的了解,我们可以更好地理解Java类加载的过程及其背后的设计哲学。这对于深入理解Java虚拟机的内部机制以及开发高质量的应用程序都至...

    Tomcat加载顺序

    与Common ClassLoader类似,但它的优先级更高,这意味着如果在两个目录下有同名的类,Shared ClassLoader加载的类将被优先考虑。 #### 6. WebApp ClassLoader WebApp ClassLoader是最底层的类加载器,它负责加载每...

Global site tag (gtag.js) - Google Analytics