Jhonney的专栏

   ----人见人爱
随笔 - 49, 文章 - 1, 评论 - 23, 引用 - 0
数据加载中……

类加载器总结

很早时就关注了classloader,但一直没有总结
1.classloader是树形结构。
         bootstrap Class Loaders负责装载java.*下的基本类 
         extension Class Loaders负责装载javax.*下的类 
         system Class Loaders负责系统(用户)实现的类

         三者的关系是 
         bootstrap class loaders是extension class loaders的父亲 
         extension class loaders是system class loaders的父亲
2.class loader的装载机制是parent delegate的模型。类的装载是委托给父class loader去查找,如果没有找到才用当前的class loader来查找。
3.不同的classLoader加载同一个类,实例是不同的,抛出castclassException
4.Class.forName是从指定的classloader中装载类,如果没有指定,也就是一个参数的时候,是从装载当前对象实例所在的classloader中装载类. 而ClassLoader的实例调用loadclass方法,是指从当前ClassLoader实例中调用类,而这个实例与装载当前所在类实例的Classloader也许不是同一个. 举个例子吧, 有A,B , C两个ClassLoader , 当前运行的类D的实例是d(装载它的是A) , 如果D中使用Class.forName那么就是使用的ClassLoader就是A,当然,也可以指定为B. 而如果D中代码找到的ClassLoader实例是C,那么就是用D来装载所指定的类.
5.Thread.currentThread().getContextClassLoader().loadClass("className"),采用当前线程的类加载器
比如:

1class A{
2..
3   public void test(){
4   ..
5   Class B =Thread.currentThread().getContextClassLoader().loadClass("className");
6   ..
7  }

8..
9}
如果将第5行中的的语句换成
1Class B=Class.forName("className"
这两种情况下calss B是一致的么?
回答:大多数情况下,是一样的,但是如果不改变 Thread的ClassLoader ,那么是否也是一样的呢?
考虑Java多线程应用,执行类A的方法体B中采用Tread的方式获得classloader是调用者的类加载器。而class.forname是加载当前类的也就是类A的类加载器。这两种情况下是可能不一致的。
在spring的环境下,类C中的类A实例通过依赖注入,如果采用Class.forName则Class B是IoC容器的类加载器;如果采用thread的话,则类加载器和加载类C的一样

posted on 2007-06-21 16:17 Jhonney 阅读(250) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: