此文参考: http://www.cnblogs.com/liu-5525/p/5614425.html
1. classLoader 如何加载 class
ClassLoader 负责将 .class 文件(可能在disk上,可能在网络上) 加载到 RAM 里面, 并为之生成对应的 [java.lang.Class] object. 当 JVM 启动的时候
会形成由三个 ClassLoader 组成的 初始类加载器 层次结构: bootstrap classloader --> extension classloader --> system classloader
bootstrap classloader: 引导(也称为原始) classloader. 它负责加载 java的核心类. 这个classloader is very special, it is not extended from java.lang.ClassLoader, 而是由JVM自身实现的。 可以通过执行以下代码来获得 bootstrap classloader 加载了哪些 core classes.
`````
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for(int i=0;i<urls.length;i++){
System.out.println(urls[i].toExternalForm());
}
sample output
`````
应为 JVM 在启动的时候自动加载它们,所以不需要再 系统属性CLASSPATH 中指定这些 class
extension classLoader: 扩展类加载器, 它负责加载 JRE 的扩展目录 (JAVA_HOME/jre/lib/ext 或者由 java.ext.dirs 系统属性指定的)
中的 jar 包. 这为引入除了 core class 以外的新功能提供了一个标准机制. 因为默认的扩展目录对所有从 同一个 JRE 中 启动 的 JVM 都是通用的
所以放入这个目录的 jar 包对所有的 JVM 和 system classloader 都是可见的. extension classLoader 是 system classloader 的parent, 而
bootstrap classloader 是 extension classloader 的 parent, 但是 bootstrap classloader 不是 一个实际的 classloader.
system classloader: 系统(应用)类加载器, 它负责在JVM被启动时,加载来自命令 java -classpath 或者 java.class.path 系统属性或者
CLASSPATH 操作系统属性 所指定的 jar 类包和类路径.
可以通过静态方法 ClassLoader.getSystemClassLoader() 找到该类加载器。如果没有特别指出,用户自定义的任何classloader都继承该加载器
classloader 加载类用的是全盘负责委托机制
全盘负责:当一个classloader加载一个class的时候,这个class所依赖的和引用的所有class 也有这个classloader 负责载入,除非是explicitly use another classloader to load the depended classes.
委托机制: 先让parent classloader 寻找,只有在parent找不到的时候才从自己的classpath中寻找.
cache 机制: classloader 采用了cache机制, 如果cache 中保存了这个class就直接返回它,如果没有才从文件中读取和转换成class,并存入 cache, 这就是为什么修改了class就必须从新启动JVM 才能生效的原因