java 类加载原理_Java 类加载基本原理

所有类都由类装载器载入,载入内存中的类对应一个 java.lang.Class 实例。

已被加载的类由该类的类加载器实例与该类的全路径名的组合标识。设有 packagename.A Class ,分别被类加载器 CL1 和 CL2 加载,则系统中有两个不同的 java.lang.Class 实例:  和  。

存在一个 Bootstrap Loader (以下简称为 BL ),由 C++ 写成,负责在虚拟机启动后一次

性加载 Java 基础类库中的所有类。其他的类装载器由 Java 写成,都是 java.lang.ClassLoader 的子类。

除 BL 之外的所有类装载器都有一个 parent 属性,指向其父装载器。查阅 java.lang.ClassLoader 的源码,不难发现类装载器的委托装载方式。protectedsynchronizedClass> loadClass(String name,booleanresolve) throwsClassNotFoundException

{

// First, check if the class has already been loaded

Class c = findLoadedClass(name);

if(c ==null) {

try{

if( parent !=null) {

c =parent .loadClass(name,false);

}else{

c = findBootstrapClass0(name);

}

}catch(ClassNotFoundException e) {

// If still not found, then invoke findClass in order

// to find the class.

c = findClass(name);

}

}

if(resolve) {

resolveClass(c);

}

returnc;

}

对于给定的类名,首先检查自己是否已加载过该类。如果没有,则首先通过父装载器加载(如果 parent==null ,则直接通过 BL 来加载,相当于 BL 是其父装载器)。如果父装载器也无法装载,才真正调用自己的 findClass() 方法来装载。

Java 基础类在 Java 虚拟机启动后由 BL 一次性载入。构成 Java 应用程序的其它类在程序运行过程中由不同类装载器按需通过 loadClass() 方法装载。

Java 程序启动过程中的类装载器

当执行“ java XXX.class ”时, java.exe 首先找到 JRE ( Java Runtime Environment ),接着找到位于 JRE 之中的 jvm.dll ,最后载入 jvm.dll 并启动虚拟机。

虚拟机一启动,先做一些初始化动作,如获取系统参数等,然后产生 BL 。 BL 加载 Java 基础类,这些类都存放在 JRE 中的 lib 目录下,可由 System.getProperty(“sun.boot.class.path”) 列出,如:C:"Program Files"Java"jre1.5.0_09"lib"rt.jar;

C:"Program Files"Java"jre1.5.0_09"lib"i18n.jar;

C:"Program Files"Java"jre1.5.0_09"lib"sunrsasign.jar;

C:"Program Files"Java"jre1.5.0_09"lib"jsse.jar;

C:"Program Files"Java"jre1.5.0_09"lib"jce.jar;

C:"Program Files"Java"jre1.5.0_09"lib"charsets.jar;

C:"Program Files"Java"jre1.5.0_09"classes

BL 然后创建 sun.misc.Launcher$ExtClassLoader ( ExtClassLoader 是定义于 sun.misc.Launcher 之内的内部类,继承自 java.lang.URLClassLoader )的实例(以下简称 EL )和sun.misc.Launcher$AppClassLoader ( AppClassLoader 是定义于 sun.misc.Launcher 之内的内部类,继承自 URLClassLoader )的实例(以下简称 AL ),并将 EL 的 parent 属性设置为null , AL 的 parent 属性设置为 EL 。

EL 在程序运行过程中按需加载保存在 JRE 的“ "lib"ext ”目录下的类。该目录可由 System.getProperty(“java.ext.dirs”) 读出,如C:"Program Files"Java"jre1.5.0_09"lib"ext

AL 在程序运行过程中按需加载的类搜索路径则是从系统参数 java.class.path 取出的字符串。 java.class.path 是由我们在执行 java.exe 时,利用 -cp 或 -classpath 或 CLASSPATH 环境变量所决定。我们应用程序用到的非 JRE 提供类的搜索路径一般都配置在 java.class.path 中。

什么时候装载类,由什么类装载器装载

1. Java 基础类由 BL 在虚拟机启动时一次性载入。

2. 包含 main() 的入口类由 AL 的 loadClass() 方法载入。

3. 由 new 关键字创建一个类的实例。该类由运行时刻包含该 new 语句的类实例的类装载器( ClassLoader.getCallerClassLoader() )的 loadClass() 方法载入。

4. 调用 Class.forName() 方法。完整的 forName() 函数版本有一个 ClassLoader 参数,用于指定用什么类装载器来装载指定类。publicstaticClass> forName(String name,booleaninitialize,

ClassLoader loader) throwsClassNotFoundException

对于 public static Class> forName(String className) 版本,是由运行时刻包含该语句的类实例的类装载器( ClassLoader.getCallerClassLoader() )的 loadClass() 方法载入。

5. 调用某个 ClassLoader 实例的 loadClass() 方法。通过该 ClassLoader 实例的 loadClass() 方法载入。应用程序可以通过继承 ClassLoader 实现自己的类装载器。

6 .装载一个类时,首先要装载该类的基类及其接口。

A Za A Za, Fighting!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值