java类加载器

一.java类加载器的种类

  1. 启动类加载器(Bootstrap):加载 java_home/jre/lib下面的类库
  2. 扩展类加载器(Extension):加载 java_home/jre/lib/ext下面的类库
  3. 系统类加载器(System/App):加载classpath下的类

二. java类加载体系之双亲委托机制

BootStrapClassLoader : 启 动 类 加 载 器 , 该 ClassLoader 是 jvm 在 启 动 时 创 建 的 , 用 于 加
载 $JAVA_HOME$/jre/lib 下面的类库

ExtClassLoader:扩展类加载器,加载 $JAVA_HOME/jre/lib/ext 下的类 库

AppClassLoader:应用程序类加载器,AppClassLoader 会加载 java 环境变量CLASSPATH 所 指 定 的 路 径 下 的 类 库 ,可 以 通 过System.getProperty(“java.class.path”)获取.

双亲委派体系是这样的:

​ 1)当 AppClassLoader 加载一个 class 时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器 ExtClassLoader 去完成。
2)当 ExtClassLoader 加载一个 class 时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader 去完成。
3)如果 BootStrapClassLoader 加载失败(例如在$JAVA_HOME$/jre/lib 里未查找到该 class),会使用ExtClassLoader 来尝试加载;
4)若 ExtClassLoader 也加载失败,则会使用 AppClassLoader 来加载,如果 AppClassLoader 也加载失败,则会报出异常 ClassNotFoundException。

为什么说双亲委派机制是安全的?

ClassLoader 加载的 class 文件来源很多,比如编译器编译生成的 class、或者网络下载的字节码。

有一些class文件是不可靠的,比如我可以自定义一个 java.lang.Integer 类来覆盖 jdk 中默认的 Integer

1
2
3
4
5
public class Integer {
public Integer(int value) {
System.exit(0);
}
}

如果没有双亲委派机制,当我们使用Integer a = new Integer(1);的时候,会加载我们使用的这个类,

那么程序就会退出。如果使用双亲委派机制,类加载器加载的是jdk的Integer。

三.类加载过程

加载:将类的字节码加载到内存,生成代表这个类的java.lang.class对象

验证:验证这个字节码是否符合虚拟机的规范

准备:为类变量分配内存

解析:将符号引用解析为直接引用

初始化:对静态变量和静态代码块进行初始化操作

触发类初始化的条件

  • 创建类的实例,new 一个对象

  • 访问某个类的静态方法或这静态变量

  • 使用反射创建一个类对象

  • 初始化一个类的子类(会先初始化子类的父类)

    总结:类的初始化步骤

    ​ 1. 如果该类还没有被加载和链接,首先执行类的加载和链接

    ​ 2.加入这个类存在直接父类,先出初始化直接父类(在一个类加载器中,类只能初始化一次);

    ​ 3.初始化静态变量以及静态代码块

文章目录
  1. 1. 一.java类加载器的种类
  2. 2. 二. java类加载体系之双亲委托机制
  3. 3. 三.类加载过程
|
载入天数...载入时分秒...