`

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总结

    博文链接:https://aga.iteye.com/blog/200410

    Java ClassLoader学习总结

    主要内容包括 Java类加载机制及加载流程,以及如何定义自己的类加载器,如何实现类的热替换。

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

    NULL 博文链接:https://lz12366.iteye.com/blog/735289

    Java中ClassLoader类加载学习总结

    本篇文章主要给大家讲述了Java中ClassLoader类加载的原理以及用法总结,一起学习下。

    ClassLoader机制详解

    由osgi引出的classLoader的大总结(整理理解ClassLoader)

    JAVA笔试总结 -- 非常全面

    JAVA笔试总结 非常全面 基本上囊括了Java所有常考知识点,并且每个知识点都有详细解释。 知识点主要包括: native,transient,volatile,strictfp,CMM,synchronized,java socket,压缩与解压缩,多线程,垃圾回收算法,...

    Java 基础核心总结 +经典算法大全.rar

    Class 类Field 类Method 类ClassLoader 类 枚举 枚举特性 枚举和普通类-样枚举神秘之处 枚举类 I/O File 类 基础 IO 类和相关方法InputStream OutputStream Reader 类Writer 类 InputStream 及其子类 ...

    Java开发面试必备知识技能总结视频合集

    Java开发工程师必看面试必备知识技能总结视频合集,视频讲解知识内容包括:HashMap源码分析与实现、JVM底层奥秘ClassLoader源码分析与案例讲解、大型网站数据库瓶颈之数据库分库分表方案实践、Spring Cloud Eureka...

    Android总结.pdf

    我们知道Java虚拟机—— JVM 是加载类的class文件的,而Android虚拟机——Dalvik/ART VM 是加载类的dex文件,而他们加载类的时候都需要ClassLoader,ClassLoader有一个子类BaseDexClassLoader,而BaseDexClassLoader...

    java常用API总结

    Java 常用API的运用,效率及技巧 1. Java面向对象基本概念 2. System ...5. Class, ClassLoader 6. Java IO系统 7. Java集合类 8. ResourceBundle, Properties 9. Exceptions 10. JDBC类库 11. 常用设计模式

    java 面试题 总结

    JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用...

    corejava基础重要知识点总结

    = 秘书 = 类加载器 = ClassLoader = 保镖 = 字节码校验器 = ByteCode Verifier = 翻译 = 解释执行器 = Interfreter 2:安全 健壮 电力 电信 银行 都会有限考虑使用java实现 3:免费 开源 4:简单 语法简单...

    JVM:类加载器子系统.pdf

    总结了类加载器子系统相关的内容,主要包括类加载器子系统的作用、ClassLoader角色、加载的过程、双亲委派机制以及沙箱安全机制等内容

    开源bbs源码java-interview-note:面试题总结

    以下是总结java面试中常见的知识点以及碰到的坑等,经历有限,需待练级! 一、java基础 实例方法和静态方法有什么不一样? Java中的异常有哪几类?分别怎么使用? 常用的集合类有哪些?比如List如何排序? ArrayList...

    jvm虚拟机总结

    我跟你讲一下我对于java的理解吧 java最大的特点就是平台无关性,一次编译,到处运行。 Java源码首先被编译成字节码...Jvm主要是由类加载器(ClassLoader),运行数据区域(Runtime Data Area),执行引擎(Execution

Global site tag (gtag.js) - Google Analytics