一段代码挺有意思:
public class Quux {
public static void main(String[] args) {
ClassLoader cl=Quux.class.getClassLoader();
System.out.println("Delegation for Quux:");
while(cl!=null){
System.out.println(cl);
cl=cl.getParent();
}
System.out.println("{bootstrap loader}");
}
}
得到得结果是:
Delegation for Quux:
sun.misc.Launcher$AppClassLoader@131f71a
sun.misc.Launcher$ExtClassLoader@15601ea
{bootstrap loader}
这锻代码展现了类加载的3个加载器(ClassLoader):
AppClassLoader是系统类加载器,(即由getSystemClassLoader()方法可得到的Loader),它主要负责加载应用类。
ExtClassLoader是扩展类加载器,默认下负责加载${JAVA_HOME}$/lib/ext目录下的类。
bootstrapLoader是引导类加载器,主要负责检查引导路径及加载核心api包。
这3个加载器先后为 boot->Ext->App ,boot是Ext的父加载器,Ext是App的父加载器,加载器是成树状的,当然也可以自己定义加载器。加载器加载的每一个类的实例都维护个指向装载器的引用,所以要得到加载器得引用很简单:getClassLoader()就行了,而getParent()则得到其父类加载器(代码中表现的很清楚了)。
类加载器有个委托规则(基本上就是偷懒规则):加载器加载类前总是要问下父加载器有没有这个类(有就不加载了-_-!),而这个过程中的ClassLoader递归集就称为一个DELEGATION.
加载的过程又有显示加载,一般用URLClassLoader:
new URLClassLoader(new URL[]{url})
这玩意玩热部署挺有意思的,tom猫里好像就有(没什么印象,汗)。
有的人也用Loader来装载配置文件,我也喜欢这么用,
getSystemClassLoader().getResourceAsStream(String res);
这个方法返回个InputStream,用properties提取下就行了,真是居家旅行必备良药啊。
new Properties().load(is);
还有隐式加载,既然叫隐式,咱明代码就干涉不到了,继承,引用一般都是隐式加载类的。
对了,java中还有个参数:-verbose,用了它就可以详细看到加载的过程。
类加载属于中级的知识了,应用内容也不是一点两点,咱又不是牛人,讲不太清楚。牛人Halloway写的component Development for the java Platform挺不错,建议看看;在IMBDevelopers上还有几篇很好的文章,有兴趣的话就去看看吧。