`

classloader 总结

    博客分类:
  • java
阅读更多
classloader对我来说一直都是很神秘的东东,这两天一直在研究,总算搞清楚了一些概念。现在写出来作为一个纪录。
classloader利用一种叫双亲委派的方法来加载类,也就是先让该classloader的parent来加载。具体的parent关系我就不再废话了。代码如下:
Java代码
  
protected synchronized Class<?> loadClass(String name, boolean resolve)   
throws ClassNotFoundException   
   {   
// First, check if the class has already been loaded   
Class c = findLoadedClass(name);   
if (c == null) {   
    try {   
    if (parent != null) {   
        c = parent.loadClass(name, false);   
    } else {   
        c = findBootstrapClass0(name);   
    }   
    } catch (ClassNotFoundException e) {   
        // If still not found, then invoke findClass in order   
        // to find the class.   
        c = findClass(name);   
    }   
}   
if (resolve) {   
    resolveClass(c);   
}   
return c;   
   }  

    protected synchronized Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException
    {
	// First, check if the class has already been loaded
	Class c = findLoadedClass(name);
	if (c == null) {
	    try {
		if (parent != null) {
		    c = parent.loadClass(name, false);
		} else {
		    c = findBootstrapClass0(name);
		}
	    } catch (ClassNotFoundException e) {
	        // If still not found, then invoke findClass in order
	        // to find the class.
	        c = findClass(name);
	    }
	}
	if (resolve) {
	    resolveClass(c);
	}
	return c;
    }
当然,虽然加载时候有parent关系,但实际上这些classloader不一定有java语义上的继承关系(或者说不必须)。
另外就是:名字空间的问题,我认为这个名字空间可以认为由两部分构成,一部分是包名,另一部分是classloader对象。也就是说:如果两个类属于同一个包下,但是由不同的classloader加载,那么他们的也不能互访default类型方法、属性。代码如下:
Java代码
public class LoaderSample2 {   
    public static void main(String[] args) {   
        try {   
            AutoResolveClassLoader loader = new AutoResolveClassLoader();   
//          ClassLoader loader = LoaderSample2.class.getClassLoader();   
            Class c = loader.loadClassInMyWay("com.cxz.cl.LoaderSample3", true);   
//          Class c = loader.loadClass("com.cxz.cl.LoaderSample3");   
            Object o = c.newInstance();   
            System.out.println(c.getClassLoader() == LoaderSample2.class.getClassLoader());//如果你的classloader仅仅重写了findclass这个会打印true,因此两个类被同一个classloader加载,而不会出现预期结果。所以你需要重写一个loadClassInYourWay方法来加载。   
            Field f = c.getDeclaredField("age");//c.getField("age");   
            int age = f.getInt(o);   
            System.out.println("age is " + age);   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
    }   
}  

public class LoaderSample2 {
	public static void main(String[] args) {
		try {
			AutoResolveClassLoader loader = new AutoResolveClassLoader();
//			ClassLoader loader = LoaderSample2.class.getClassLoader();
			Class c = loader.loadClassInMyWay("com.cxz.cl.LoaderSample3", true);
//			Class c = loader.loadClass("com.cxz.cl.LoaderSample3");
			Object o = c.newInstance();
			System.out.println(c.getClassLoader() == LoaderSample2.class.getClassLoader());//如果你的classloader仅仅重写了findclass这个会打印true,因此两个类被同一个classloader加载,而不会出现预期结果。所以你需要重写一个loadClassInYourWay方法来加载。
			Field f = c.getDeclaredField("age");//c.getField("age");
			int age = f.getInt(o);
			System.out.println("age is " + age);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

LoaderSample2和LoaderSample3是同一个包下的类,如果由同一个classloader加载,则通过反射获得LoaderSample3.age属性是可行的(该属性的类型时default)如果利用我自己写的一个classloader加载,则由于classloader不同,则不能访问该age属性。 

值得注意的是,如果你建立你自己的classloader,javadoc中建议override findclass方法,但是再loadclass的过程中还会采取双亲委派的模式,也就是说,不能把你要加载的class防到classpath中,否则jvm还会利用appclassloader来加载。我就是采用重新写了一个loadClassInMyWay方法,消除双亲委派。具体代码如下: 
Java代码 
public synchronized Class loadClassInMyWay(String name, boolean resolve)   
        throws ClassNotFoundException {   
    // First, check if the class has already been loaded   
    Class c = findLoadedClass(name);   
    if (c == null) {   
        c = this.findClass(name);//该方法由我override   
    }   
    return c;   
}  

	public synchronized Class loadClassInMyWay(String name, boolean resolve)
			throws ClassNotFoundException {
		// First, check if the class has already been loaded
		Class c = findLoadedClass(name);
		if (c == null) {
			c = this.findClass(name);//该方法由我override
		}
		return c;
	}
其中然我很迷惑的一点是:如果我单纯的override方法:loadClass,运行时刻会给我报异常ClassCircularityError不明白为什么~

以下摘自ibm网站,具体网址:https://www6.software.ibm.com/developerworks/cn/education/java/j-classloader/tutorial/j-classloader-2-2.shtml
总结classloader的通常作用:
* 在执行非置信代码之前,自动验证数字签名
* 使用用户提供的密码透明地解密代码
* 动态地创建符合用户特定需要的定制化构建类

  • cl.rar (1.4 KB)
  • 下载次数: 12
分享到:
评论

相关推荐

    ClassLoader总结

    总结来说,对ClassLoader的理解对于Java开发者来说至关重要,它关乎程序的运行效率、安全性和可扩展性。通过深入学习和实践,我们可以更好地掌握Java平台的动态加载机制,提升软件设计和实现的能力。

    Java ClassLoader学习总结

    Java ClassLoader学习总结 Java 类加载机制是 Java 中一个非常重要的机制,它负责加载 Class 文件到 JVM,以供程序使用。ClassLoader 是 Java 中的一个抽象类,它的主要作用是加载 Class 文件到 JVM 中。...

    ClassLoader

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

    Java ClassLoader定制实例

    总结来说,Java ClassLoader的定制是一项强大的技术,它可以让我们实现动态加载代码、构建灵活的插件系统等功能。然而,这也需要开发者对Java的内存管理和类加载机制有深入的理解,以便正确且安全地使用。通过研究...

    java ClassLoader机制及其在OSGi中的应用

    总结来说,Java ClassLoader机制是Java平台的基础,它使得程序能够动态地加载和管理类。而在OSGi这样的模块化环境中,ClassLoader机制得到了进一步的发展,实现了更加精细的类加载控制和更好的模块隔离。理解并掌握...

    ClassLoader类加载机制和原理详解

    总结,理解ClassLoader的加载机制和原理对于优化程序性能、设计可扩展的系统至关重要。通过自定义ClassLoader,开发者可以实现许多高级功能,如动态加载、插件机制等,从而增强软件的灵活性和可维护性。同时,掌握...

    关于Classloader的总结!loadClass的分析和加载细节的分析

    在Java编程语言中,`Classloader`(类加载器)是一个至关重要的组件,它负责将类的`.class`文件从磁盘加载到JVM(Java虚拟机)内存中,使得程序能够执行。这篇博文主要围绕`Classloader`的`loadClass`方法进行深入...

    classloader 加密解密应用程序 ,反编译class

    总结来说,`ClassLoader`在Java中扮演着核心角色,负责加载和管理类。通过自定义`ClassLoader`,我们可以实现加密解密应用程序,提升代码的安全性。同时,结合混淆技术和其他反编译防御措施,可以有效地保护我们的...

    classloader体系结构(含hotswap)

    Java的类加载器(ClassLoader)...总结来说,Java的类加载器体系结构是其动态性和灵活性的关键组成部分。通过理解这个体系,开发者能够更好地管理类的加载,实现代码的动态加载和替换,优化应用程序的性能和维护性。

    Understanding the Java ClassLoader

    #### 四、总结 通过本教程的学习,你将能够理解Java ClassLoader的基本概念及其工作原理,并学会如何创建自定义的ClassLoader。自定义ClassLoader不仅能够扩展JVM的功能,还能够在实际项目中解决特定问题,如动态...

    j-classloader-ltr

    #### 六、总结 通过学习这篇教程,读者不仅可以了解到类加载器的基本概念及其在Java运行时系统中的作用,还能够掌握如何构建自定义的类加载器。这对于那些希望深入理解Java内部机制或者需要实现特定功能(例如动态...

    ClassLoader类加载器

    总结来说,ClassLoader是Java运行时环境的重要组件,它按照委托模型加载类,提供了扩展和自定义的可能性。理解和掌握ClassLoader的工作原理以及如何自定义,对于提升Java应用的灵活性和安全性具有重要意义。

    Java ClassLoader原理

    #### 总结 Java中的类加载机制是其强大功能的关键组成部分之一。通过支持懒加载、类型安全链接、用户可定义的加载策略以及多命名空间等功能,Java不仅提高了系统的性能和安全性,还极大地增强了开发者的灵活性和...

    Java ClassLoader Tutorial.zip

    总结,Java ClassLoader是Java平台的关键特性,理解其工作原理和应用场景对于优化系统性能、设计可扩展的系统至关重要。通过本教程,读者应能掌握如何利用ClassLoader实现动态加载、安全隔离和版本控制等功能,提升...

Global site tag (gtag.js) - Google Analytics