`
nanapoleon
  • 浏览: 48148 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

ClassLoader学习记录

阅读更多
如果是长期的学习计划,我还是比较倾向于学习一本完整的书籍,或者至少是其中的几章重要的章节,这样会比较系统,不会像平时那样的东一榔头西一棒子,如果学得和我们平时工作的息息相关,经常会发现才学的就能被用上。其实,只不过以前不会发现这些隐藏的东西罢了,不信?你可以试试看。
啰嗦了这么多,也该说点实际的了。
我的切入点是java核心编程卷2第九章,安全。第一节是类加载器。这一部分以前只是知道,但并不了解,看来有必要深入一下。翻了翻书,如果不知道反射的童鞋,应该就不用往下看了,你要硬看,还不如刷会微博。(哥,你真刷去了?)
ok.先说一些废话(不好意思,又来了),这章介绍的是安全,所以,整章应该是以安全角度来介绍所有知识的,不过,也不妨碍我们学习类加载器,多学点安全知识罢了。
那么,就先说说,Java编译器吧。它会为虚拟机转换源指令。虚拟机代码存储在.class的类文件中,这些文件就会包含某个类,或者接口的实现。还需要一个解释器,它来把所有的虚拟机的指令集,解释成目标机器的机器语言,这个就偏底层了,先不考虑。
这样,虚拟机是如何加载一些所需要的类文件呢?这里,假设程序从MyProgram.class开始运行,下面是虚拟机的执行步骤:
1.虚拟机有一个用于加载类文件的机制。
2.如果MyProgram类拥有类型为另一个类的实例变量,或者父类,那么这些类也会被加载。
3.接着,虚拟机执行MyProgram的main方法。
4.如果main方法调用了更多的类,那么接下来就会加载这些类。

上面所说的类加载机制,并不实用单个类加载器,每个java程序至少拥有三个类加载器。
引导类加载器:这个事由c语言实现的它没有ClassLoader对象,如String.class.getClassLoader(),会返回null。它通常会从rt.jar中进行加载。
扩展类加载器:用于从目录jre/lib/ext目录加载“标准的扩展”(因为它不会使用类路径),可以放jar到此路径下,即使没有任何类路径。
系统类加载器:用于加载应用类。它在有CLASSPATH环境变量或者-classpath命令行选项设置的目录里找到这些类。

这些类加载器是有父子结构的,父亲会得到先行加载的机会,所以,一个系统类加载器加载一个系统类(如java.util.ArrayList)时,它首先要求扩展类加载器进行加载,扩展类会首先要求引导类加载器加载,引导类加载器查找并加载rt.jar中的这个类。

插件架构的程序:
URL url = new URL("file://path/to/plugin.jar");
URLClassLoader pluginLoader = new URLClassLoader(new URL[] { url });
Class<?> cl = pluginLoader.loadClass(mypackage.MyClass);

因为在URLClassloader构造器中指定父类加载器(不太明白,难道是代码内部写的?),因此pluginLoader的父亲就是系统类加载器,那么,层次如下:
Bootstrap类加载器 rt.jar
Extension类加载器 jre/lib/ext
System类加载器   CLASSPATH
Plugin类加载器   plugin.jar   

这样,想象一场景,我们在插件包中(或者不在插件包中,但为了说明类加载器的传递问题)使用Class.forName(classNameStr),这个类是插件jar中的类。
那么,如果使用Plugin类加载器以上三层的任意类加载器,都不会得到这个类。
有两种方法可以避免:
1.使用参数传递进来ClassLoader对象,使用此对象对类进行加载。
2.使用上下文类加载器。每个线程都有一个对类加载器的引用,成为上下文加载器,主线程的为系统类加载器,当新线程被创建,默认会设置成系统类加载器,也可以:
Thread t = Thread.currentThread();
t.setContextClassLoader(loader);
那么我们使用时:
Thread t = Thread.currentThread();
ClassLoader loader = t.getContextClassLoader();
Class c1 = loader.loadClass(className);

所以,如果你编写了一个按名字来加载类的方法,最好让调用者在传递显示的类加载器和使用上下文加载器之间进行选择,而不是直接使用此方法所属的类的类加载器。

类加载器有了初步的认识了,细水长流,下次再继续吧。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics