Java Classloader技术

本文深入探讨了Java类加载机制中的关键方法,包括loadClass、defineClass、findSystemClass等,详细解释了每个方法的功能、参数及工作流程,并提供了一个自定义类加载器的实现示例。

https://www6.software.ibm.com/developerworks/cn/education/java/j-classloader/tutorial/j-classloader-3-2.shtml

 


方法 loadClass 第 2 页(共 8 页)

ClassLoader.loadClass() 是 ClassLoader 的入口点。其特征如下:

 

Class loadClass( String name, boolean resolve );

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

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

在 Java 版本 1.1 和以前的版本中,loadClass 方法是创建定制的 ClassLoader 时唯一需要覆盖的方法。(Java 2 中 ClassLoader 的变动 提供了关于 Java 1.2 中 findClass() 方法的信息。)

 

方法 defineClass 第 3 页(共 8 页)



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

defineClass 管理 JVM 的许多复杂、神秘和倚赖于实现的方面 -- 它把字节码分析成运行时数据结构、校验有效性等等。不必担心,您无需亲自编写它。事实上,即使您想要这么做也不能覆盖它,因为它已被标记成最终的。

 


方法 findSystemClass 第 4 页(共 8 页)

findSystemClass 方法从本地文件系统装入文件。它在本地文件系统中寻找类文件,如果存在,就使用 defineClass 将原始字节转换成 Class 对象,以将该文件转换成类。当运行 Java 应用程序时,这是 JVM 正常装入类的缺省机制。(Java 2 中 ClassLoader 的变动 提供了关于 Java 版本 1.2 这个过程变动的详细信息。)

对于定制的 ClassLoader,只有在尝试其它方法装入类之后,再使用 findSystemClass 。原因很简单:ClassLoader 是负责执行装入类的特殊步骤,不是负责所有 类。例如,即使 ClassLoader 从远程的 Web 站点装入了某些类,仍然需要在本地机器上装入大量的基本 Java 库。而这些类不是我们所关心的,所以要 JVM 以缺省方式装入它们:从本地文件系统。这就是 findSystemClass 的用途。

其工作流程如下:

 

  • 请求定制的 ClassLoader 装入类。
  • 检查远程 Web 站点,查看是否有所需要的类。
  • 如果有,那么好;抓取这个类,完成任务。
  • 如果没有,假定这个类是在基本 Java 库中,那么调用 findSystemClass ,使它从文件系统装入该类。

在大多数定制 ClassLoaders 中,首先调用 findSystemClass 以节省在本地就可以装入的许多 Java 库类而要在远程 Web 站点上查找所花的时间。然而,正如,在下一章节所看到的,直到确信能自动编译我们的应用程序代码时,才让 JVM 从本地文件系统装入类。

 


方法 resolveClass 第 5 页(共 8 页)

正如前面所提到的,可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的 loadClass 时,可以调用 resolveClass ,这取决于 loadClassresolve 参数的值。

 


方法 findLoadedClass 第 6 页(共 8 页)

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

 


组装 第 7 页(共 8 页)

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

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

 

  • 调用 findLoadedClass 来查看是否存在已装入的类。
  • 如果没有,那么采用那种特殊的神奇方式来获取原始字节。
  • 如果已有原始字节,调用 defineClass 将它们转换成 Class 对象。
  • 如果没有原始字节,然后调用 findSystemClass 查看是否从本地文件系统获取类。
  • 如果 resolve 参数是 true ,那么调用 resolveClass 解析 Class 对象。
  • 如果还没有类,返回 ClassNotFoundException
  • 否则,将类返回给调用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值