一、为什么要有类加载器
Java不像一些静态编译型的语言,是在编译期间就进行连接的,而是在运行期间加载类的。这也为Java提供了极大的灵活性。
二、什么是类加载
1. 类的生命周期
共7步: 加载-->(验证-->准备-->解析)-->初始化-->使用-->卸载
其中(验证-->准备-->解析) 又称为 连接.
从加载到初始化 就是类的加载.
2. 类加载的时机
只有对类进行主动引用时才会加载, 而被动引用则不会加载.
1) 主动引用
new对象, 访问静态变量, 调用静态方法
反射
主类
初始化子类时, 会先初始化父类
对于>JDK1.7, 遇到MethodHandle 时,也会初始化
2) 被动引用
常量: 常量在常连池中, 已经和类基本没关系了
数组的定义
通过子类访问父类的静态字段
三、类加载器的分类
按照优先级关系如下:
1. Bootstrap 引导(启动)类加载器 jvm的一部分 JAVA_HOME/lib
2. Extension 扩展类加载器 java JAVA_HOME/lib/ext
3. Application 系统类加载器 java classpath
4. 自定义类加载器 java
当加载一个类时, 会先委托给父类进行加载, 当父类加载不了时, 才会由子类进行加载. 这就是双亲委派模型.
如果要自定义加载器, 继承ClassLoader, 并重写findClass 方法即可.
四、破坏双亲委派模型
由于双亲委派模型的限制, 越是基础的类库,就不能加载上层的类了. 例如 JNDI.
于是就引入了线程上下文类加载器.