Goingmm

  BlogJava :: 首页 :: 新随笔 ::  :: 聚合  :: 管理 ::
  82 随笔 :: 15 文章 :: 452 评论 :: 0 Trackbacks

类装载器负责把类装入 Java 虚拟机(JVM)。简单的应用程序可以用 Java 平台内置的类装载工具装载类;更复杂的应用程序则倾向于定义自己定制的类装载器。但是,不论使用哪种类装载器,在类装载过程中都可能发生许多问题。如果想避免这类问题,需要理解类装载的基本机制。

 

类装载器委托模型

classload.gif 

注意:在这个继承体系中,父类装载器始终具有优先装载的权力。比如子类接收到需要装载Person类的请求,它会先委托给父类去尝试装载,父类装载失败,子类才会接着尝试装载。但是,都被规定了各自的装载空间。[例如:“System Class Loader” 不会到/jre/lib/* 下去load]

 

引导类装载器(也称作基本(primordial 类装载器):

它本身是C++写的程序。可以独立运行,它是JVM的运行起点。不能由 Java 代码实例化。(通常是因为它是作为 VM 本身的一部分实现的。)这个类装载器可以从启动的类路径装载核心系统类,通常是位于 jre/lib 目录的 JAR 文件。

扩展(extension 类装载器(也称作标准扩展 类装载器):

是引导类装载器的一个孩子。它的主要职责是从扩展目录装载类,通常位于 jre/lib/ext 目录。这提供了简单地访问新扩展的能力,例如不同的安全扩展,不需要修改用户的类路径即可实现。

系统(system 类装载器(也称作应用程序 类装载器):

负责从 CLASSPATH 环境变量指定的路径装载代码。默认情况下,这个类装载器是用户创建的任何类装载器的父类。这也是 ClassLoader.getSystemClassLoader() 方法返回的类装载器。

 

类装载的阶段

一个类的运行,JVM做会以下几件事情: 1、类装载 2、链接 3、初始化 4、实例化

一个类的装载可分成三个阶段:类装载、链接和初始化

 

类装载的 阶段示意图

loadstep.gif
   装载
阶段包括:找到必要的类(通过查找每个类路径)并装载字节码。在 JVM 中,装载阶段为类对象提供了非常基本的内存结构。在这一阶段不处理方法、字段和引用的其他类。所以,类还不能使用。

 

   链接 是三个阶段中最复杂的一个。可以把它分成三个主要阶段:

  • 字节码验证。 类装载器对于类的字节码要做许多检测,以确保格式正确、行为正确。
  • 类准备。 这个阶段准备代表每个类中定义的字段、方法和实现接口所必需的数据结构。
  • 解析。   这个阶段,类装载器装载类所引用的其他所有类。可以用许多方式引用类:
    • 超类
    • 接口
    • 字段
    • 方法签名
    • 方法中使用的本地变量

   在初始化 阶段,类中包含的静态初始化器都被执行。在这一阶段末尾,静态字段被初始化成默认值。
   
在这三个阶段末尾,类被完整地装载,可以使用了。请注意可以用惰性方式执行类装载,所以类装载过程的某些部分可能在第一次使用类的时候[比如:初始化]才执行,而不是在装载时执行。

举例说明:

         Class.forName(args[0], false,off.getClass().getClassLoader());

告诉JVM不需在load class之后进行initial的工作。这样,将initial的工作推迟到了newInstance的时候进行。所以,static块的绝对不是“只在类被第一次实例化的时候才会被仅仅调用一次”,而应

该是在类被初始化的时候,仅仅调用一次

         Class.forName(args[0], true,off.getClass().getClassLoader());

         告诉JVMload class之后立即进行initial的工作

 

显式装载与隐式装载

类装载的方式有两种 —— 显式 隐式,两者之间有些细微差异。

显式 类装载发生在使用以下方法调用装载的类的时候:

  • cl.loadClass()cl java.lang.ClassLoader 的实例)
  • Class.forName()(启动的类装载器是当前类定义的类装载器)

   当调用其中一个方法的时候,指定的类(以类名为参数)由类装载器装载。如果类已经装载,那么只是返回一个引用;否则,装载器会通过委托模型装载类。

   隐式 类装载发生在由于引用、实例化或继承导致装载类的时候(不是通过显式方法调用)。在每种情况下,装载都是在幕后启动的,JVM 会解析必要的引用并装载类。与显式类装载一样,如果类已经装载了,那么只是返回一个引用;否则,装载器会通过委托模型装载类。例如:Person p = new Person();

    类的装载通常组合了显式和隐式类装载。例如,类装载器可能先显式地装载一个类,然后再隐式地装载它引用的所有类。

 

参考:IBM技术文档

 

Goingmm 2006-2-23 

 

posted on 2006-02-23 09:51 Goingmm 阅读(485) 评论(0)  编辑  收藏 所属分类: Reading Note

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


网站导航: