1.2 类加载子系统(一)

83 阅读2分钟

1.2 类加载子系统

1.2.1 类加载的时机

类加载主要有四个时机:

  1. 遇到 new 、 getstatic 、 putstatic 和 invokestatic 这四条指令时,如果对应的类没有初始化,则要对对应的类先进行初始化。
public class Student{
    private static int age ;
    public static void method(){
    }
}
//Student.age
//Student.method();
//new Student();
  1. 使用 java.lang.reflect 包方法时,对类进行反射调用的时候。
Class c = Class.forname("com.hero.Student");
  1. 初始化一个类的时候发现其父类还没初始化,要先初始化其父类。
  2. 当虚拟机开始启动时,用户需要指定一个主类(main),虚拟机会先执行这个主类的初始化。

1.2.2 类加载的过程

类加载主要做三件事:

  1. 全限定名称 ==> 二进制字节流加载class文件
  2. 字节流的静态数据结构 ==> 方法区的运行时数据结构
  3. 创建字节码Class对象

一个类的一生:

image.png

可以从哪些途径加载字节码?

image.png

1.2.3 类加载器

JVM的类加载是通过ClassLoader及其子类来完成的。

image.png

检查顺序是自底向上: 加载过程中会先检查类是否被已加载,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。

加载的顺序是自顶向下: 也就是由上层来逐层尝试加载此类。

image.png

启动类加载器(Bootstrap ClassLoader): 负责加载 JAVA_HOME\lib 目录中的,或通过-Xbootclasspath参数指定路径中的,且被虚拟机认可(按文件名识别,如rt.jar)的类。由C++实现,不是ClassLoader的子类

扩展类加载器(Extension ClassLoader): 负责加载 JAVA_HOME\lib\ext 目录中的,或通过java.ext.dirs系统变量指定路径中的类库。

应用程序类加载器(Application ClassLoader): 负责加载用户路径classpath上的类库

自定义类加载器(User ClassLoader): 作用:JVM自带的三个加载器只能加载指定路径下的类字节码,如果某些情况下,我们需要加载应用程序之外的类文件呢?就需要用到自定义类加载器,就像是在汽车行驶的时候,为汽车更换轮子。 比如本地D盘下的,或者去加载网络上的某个类文件,这种情况就可以使用自定义加载器了。

举个栗子:JRebel

image.png

学习:Java 业务开发常见错误 100 例学习笔记