classload 加载机制

在对ExtClassLoader getParent()的时候,会抛出NullPointException. Class是在需要使用的时候才被系统加载,而ClassLoader是用来加载Class的,一共有三种默认ClassLoader:

  1. Bootstrap loader
  2. ExtClassLoader
  3. AppClassLoader

Bootstrap loader是由C写成,而后两者由Java写成。在Java程序启动的时候,会依次按照以上排列顺序加载class loader, 并把上一个classloader设为自己的parent.  具体如下图:

默认情况下,各个classloader会在如下目录搜索class并加载: 

  1. Bootstrap loader:  sun.boot.class.path中指定位置的類別,預設是JRE所在目錄的classes下之.class檔案,或lib目錄下.jar檔案中(例如rt.jar)
  2. ExtClassLoader: java.ext.dirs中 指定位置的類別,預設是JRE目錄下的lib\ext\classes目錄下的.class檔案,或lib\ext目錄下的.jar檔案
  3. AppClassLoader: classpath 指向的目录下的class或者jar包

在加载的时候,每个classloader都会先把加载的优先权交给其“父classloader”,只有在“父classloader”找不到资 源的情况下才让给下一级别的classloader加载。对每个Class对象,我们可以用getClassLoader()来得到加载这个Class的 ClassLoader,对每个classloader也可以用getParent()来得到父级别的ClassLoader

这里要注意Bootstrap是C写的,没有对应的java object,所以:

  • 在对ExtClassLoader getParent()的时候,会抛出NullPointException. 
  • 当我们把Class文件放在JRE目录的classes目录下,拿这个Class的ClassLoader的时候只会拿到NULL.

我们可以利用URLClassLoader类来自定义ClassLoader,

URL url = new URL("file:/d:/workspace/");
ClassLoader urlClassLoader = new URLClassLoader(new URL[] {url});
Class c = urlClassLoader.loadClass("SomeClass");

loader会自动成为AppClassLoader的子Loader。当我们用两个自定义loader加载class的时候,这个class如果是在上级AppClassLoader的目录被找到,则只有一个对象生成。 如果是各自的自定义loader找到,则会生成2个对象。

此文基于以下两篇文章:

posted on 2011-04-22 08:44  廉帅博  阅读(607)  评论(0)    收藏  举报