herodby
技术 笔记
posts - 14,  comments - 14,  trackbacks - 0
什么是 ClassLoader?
      

      在流行的商业化编程语言中,Java 语言由于在 Java 虚拟机 (JVM) 上运行而显得与众不同。这意味着已编译的程序是一种特殊的、独立于平台的格式,并非依赖于它们所运行的机器。在很大程度上,这种格式不同于传统的可执行程序格式。

与 C 或 C++ 编写的程序不同,Java 程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应于一个 Java 类。

此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader 是 JVM 中将类装入内存的那部分。

而且,Java ClassLoader 就是用 Java 语言编写的。这意味着创建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小细节。
     java得classloader 不但可以使你运行本地得class类,你也可以定制classloader运行来自远程的字节代码.     

    ClassLoader 的基本目标是对类的请求提供服务。当 JVM 需要使用类时,它根据名称向 ClassLoader 请求这个类,然后 ClassLoader 试图返回一个表示这个类的 Class 对象。

通过覆盖对应于这个过程不同阶段的方法,可以创建定制的 ClassLoader。

    通常当你需要动态加载资源的时候, 你至少有三个ClassLoader可以选择:

²        系统类加载器或叫作应用类加载器 (system classloader or application classloader)

²        当前类加载器

²        当前线程类加载器
第一种:系统类加载器
    系统类加载器(system classloader). 这个类加载器处理-classpath下的类加载工作, 可以通过ClassLoader.getSystemClassLoader()方法调用. ClassLoader下所有的getSystemXXX()的静态方法都是通过这个方法定义的. 在你的代码中, 你应该尽量少地调用这个方法,以其它的类加载器作为代理. 否则你的代码将只能工作在简单的命令行应用中, 这个时候系统类加载器(system classloader)JVM最后创建的类加载器. 一但你把代码移到EJB, Web应用或Java Web Start应用中, 一定会出问题 .

Class.loadClass( String name, boolean resolve );

       name 参数指定了 JVM 需要的类的名称,该名称以包表示法表示,如 Foo 或  java.lang.Object

       resolve 参数告诉方法是否需要解析类。在准备执行类之前,应考虑类解析。并不总是需要解析。如果 JVM 只需要知道该类是否存在或找出该类的超类,那么就不需要解析。
    

      defineClass 方法是 ClassLoader 的主要诀窍。该方法接受由原始字节组成的数组并把它转换成 Class 对象。原始数组包含如从文件系统或网络装入的数据。

defineClass 管理 JVM 的许多复杂、神秘和倚赖于实现的方面 -- 它把字节码分析成运行时数据结构、校验有效性等等。不必担心,您无需亲自编写它。事实上,即使您想要这么做也不能覆盖它,因为它已被标记成最终的。
   方法 findSystemClass
   findSystemClass 方法从本地文件系统装入文件。它在本地文件系统中寻找类文件,如果存在,就使用 defineClass 将原始字节转换成 Class 对象,以将该文件转换成类。当运行 Java 应用程序时,这是 JVM 正常装入类的缺省机制.
   如果 ClassLoader 不能找到类,它会请求父代 ClassLoader 来执行此项任务。所有 ClassLoaders 的根是系统 ClassLoader,它会以缺省方式装入类 -- 即,从本地文件系统。

     findLoadedClass 充当一个缓存:当请求 loadClass 装入类时,它调用该方法来查看 ClassLoader 是否已装入这个类,这样可以避免重新装入已存在类所造成的麻烦。应首先调用该方法。

     

让我们看一下如何组装所有方法。

我们的 loadClass 实现示例执行以下步骤。(这里,我们没有指定生成类文件是采用了哪种技术 -- 它可以是从 Net 上装入、或者从归档文件中提取、或者实时编译。无论是哪一种,那是种特殊的神奇方式,使我们获得了原始类文件字节。)

  • 调用 findLoadedClass 来查看是否存在已装入的类。

  • 如果没有,那么采用那种特殊的神奇方式来获取原始字节。

  • 如果已有原始字节,调用 defineClass 将它们转换成 Class 对象。

  • 如果没有原始字节,然后调用 findSystemClass 查看是否从本地文件系统获取类。

  • 如果 resolve 参数是 true,那么调用 resolveClass 解析 Class 对象。

  • 如果还没有类,返回 ClassNotFoundException

  • 否则,将类返回给调用程序。
    第二种选择: 当前上下文环境下的类加载器.
     根据定义 , 当前类加载器就是你当前方法所属的类的加载器 . 在运行时类之间动态联编 , 及调用 Class.forName,() Class.getResource() 等类似方法时 , 这个类加载器会被隐含地使用 .


posted on 2006-08-04 12:29 邓兵野 阅读(919) 评论(2)  编辑  收藏 所属分类: jdk技术

FeedBack:
# re: 了解classloader
2006-08-04 17:31 | dylan
不错,讲的很清楚,期待后续佳作  回复  更多评论
  
# re: 了解classloader
2006-09-29 14:11 | kurt
牛!  回复  更多评论
  

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


网站导航:
 

<2006年8月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿(2)

随笔分类

随笔档案

文章分类

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜