关于java class loader的理解笔记

Posted on 2007-04-03 12:27 久城 阅读(2500) 评论(3)  编辑  收藏 所属分类: Java理解笔记

JAVA中的一切都是以类的形式存在的(除少数底层的东西,那些我就不清楚是怎么回事了)。我们运行的接口是一个类,运行中所涉及到的对象也都是类对象。下面,我们来研究下,我所理解的类的加载机制。

比如我们有一个Student类,也就是经过编译后,是一个Student.class文件。当我们的程序运行的过程中,第一次实例化一个student对象的时候,系统首先要做的就是加载Student这个类。也就是把Student.class以字节玛的形势加载到内存中(并通过defineClass()这个方法转变成Class对象,最终以Class对象的形式存储在内存中)。这个加载的过程就是由类加载器来完成的。

一般的,在程序启动之后,系统会主要会有三个类加载器:Bootstrap Loader、ExtClassLoader与AppClassLoader。

Bootstrap Loader是由C++撰写的,它主要负责搜索JRE所在目录的classes或lib目录下的.jar文件(例如rt.jar)是否需要被加载(实际上是由系统参数sun.boot.class.path来指定);ExtClassLoader主要负责搜索JRE所在目录的lib/ext 目录下的classes或.jar中是否需要被加载(实际上是由系统参数java.ext.dirs指定);AppClassLoader则是搜索 Classpath中是否有指定的classes需要被载入(由系统参数java.class.path指定)。

简单的说,Bootstrap Loader、ExtClassLoader这两个类加载器,主要是加载系统类库里的类。我们自己编辑的类一般都是由AppClassLoader来加载。当我们遇到如下代码的时候:

Student stu  = new Student();
//实例化一个Student类的对象stu

AppClassLoader首先会到classpath下去寻找Student.class文件。(找不到则会抛出ClassNotFoundException异常)找到之后便会把Student这个类以二进制的形式存储到内存中。这个过程也就是对Student类加载的过程。然后用我们加载到内存中的Student类去实例化一个Student对象stu。

以上就是所谓的隐式的类的加载过程。但是有些时候需要我们自定义一个类的加载器,这个时候就需要我们模仿这个过程,显示的加载我们自己所需要的类。比如,我们自定义一个类的加载器MyClassLoader,那我们利用我们自定义的这个加载器,显示的去加载一个类的过程也是这样的:

1.寻找类文件。
这里的灵活性比较大,我们可以自己去设计如何去寻找类文件以及去哪里寻找类文件。比如一些非本地的类文件,通过系统的类加载器无法加载到这些类,这个时候,我们就可以利用自定义的类加载器指定路径去寻找。
2.加载类文件。
找到我们所要加载的类之后,通过MyClassLoader的defineClass()方法,把这个类加载到指定的内存中。这里我们可以自己设定存储类的内存空间,比如把我们加载的类都统一放到一个变量数组里(至于系统的类加载到内存中是以什么样的形式存储再内存中的,我还不清楚,只知道是以二进制的形式保存的,可以用一个Class对象去引用)。
3.创建类对象。
我接触的时候还不大理解,其实这里是应用我们自己加载到内存中的类,去实例化一个对象。以下代码可以参考:

import java.net.MalformedURLException;
import java.net.URL;

class MyClassLoader {
    
public static void main(String[] args) throws MalformedURLException,
            ClassNotFoundException 
{
        URL url1 
= new URL("file:/d:/workspace/");
        
// 指定路径,相当于classpath的意思。
        myClassLoader myClassLoader = new MyClassLoader(new URL[] { url1 });
        
// 用这个路径创建一个myClassLoader对象。这里随你所定义的ClassLoader而定。
        Class c1 = myClassLoader.loadClass("Student");
        
// 用自定义的类加载器,去显式的加载一个类。返回一个Class对象。
        Student stu = c1.newInstance();
        
// 用这个Class对象就可以产生一个ClassLoaderTest的实例。
    }

}

正在学习中,理解的还不够准确。保持更新。

欢迎来访!^.^!
本BLOG仅用于个人学习交流!
目的在于记录个人成长.
所有文字均属于个人理解.
如有错误,望多多指教!不胜感激!

Feedback

# re: 关于java class loader的理解笔记  回复  更多评论   

2007-04-11 14:27 by Web 2.0 技术资源
好玩!!!!!!!!

# re: 关于java class loader的理解笔记  回复  更多评论   

2007-04-16 19:18 by liji
猴子的粑粑 ---缘分啊!
这都能碰到,这么短的时间你就能理解到这个层次,佩服:D 你太有才了,呵呵,学习 - -

# re: 关于java class loader的理解笔记[未登录]  回复  更多评论   

2008-11-05 22:59 by Scott
AppClassLoader首先会到classpath下去寻找Student.class文件,应该是AppClassLoader会调用父loader去加载,没加载到的话才会由AppClassLoader去加载, JDK doc 引用如下:


The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When called upon to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the bootstrap class loader, does not itself have a parent but may serve as the parent of a ClassLoader instance

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


网站导航:
 

Copyright © 久城