乍一看到ClassLoader,我的第一感觉就是这东西好神秘啊。然后找了一下资料,略懂了一点皮毛,然后在这里和大家分享一下,这篇文章在接下来的日子里会不断的被更新,希望会越来越完善。
首先,我们了解一下ClassLoader是干什么用的呢?
大家都知道,JVM解析的是Class的字节码文件,那么JVM怎样来加载这个字节码文件呢,没错,ClassLoader负责了这项重要的工作。
JDK中主要有以下几种ClassLoader:
a, Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.
b, Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作
c, System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作.
b, User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.
那么我们能用ClassLoader做什么事情呢?
如果我们想动态的加载一个类,比如我们想实现一个Hot-Swap的应用,我们期望一个刚开发的高版本的Class在不关闭JVM的情况下让它工作,此时我们就可以实现我们自己的ClassLoader,重写里面的findClass方法。
这里我们需要注意ClassLoader的双亲委托模式,即定义ClassLoader加载一个类之前,要先委托它的父亲ClassLoader进行加载,只有当父亲ClassLoader无法加载成功后,才会由自己加载。为什么要使用这种双亲委托模式呢?
第一个原因就是因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
第二个原因就是考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义的ClassLoader 无法加载另外的String。
参考资料:
http://www.iteye.com/topic/136427
http://www.iteye.com/topic/83978
Kyle Wang