Java基本知识:Java虚拟机是如何加载类的

Java虚拟机类加载的先后顺序是加载,链接以及初始化三个操作。
引用类型在Java虚拟机中认为有三种,接口,类与数组类。
数据类是Java虚拟机直接生成的,其他两种则有对应的字节流。
字节流最常见的形式是Java编译器生成的class文件。除此之外可以在程序内部直接生成。不同形式的字节流都会被加载到虚拟机哄,称为类或者接口。

加载

加载:查找字节流,并根据此创建类的过程。数组类能被Java虚拟机直接接受,但是接口与类需要借助类加载器来完成查找字节流的操作。
除了启动类加载器之外,其他的类加载器都是ClassLoader下子类。
需要先把启动类加载器加载到虚拟上才能加载其他类型的类加载器。

  • Java9之前启动类加载器负责加载最为基础,最为重要的类。
    扩展类加载器的父类加载器是启动类加载器。负责加载相对次要,但又通用的类、存放在lib/ext下面的jar包中的类。
    应用类加载器的父类加载器则是扩展类加载器。负责加载应用程序路径下的类。系统变量,或者环境变量,虚拟机参数-cp/-classpath,三者下的类。。
  • Java9 之后引入模块系统,加载器进行了修改。
    扩展类加载器改为平台类加载器,除了少数几个关键模块是由启动类加载加载之外,其他模块都是有平台类加载器加载。

可以引入自定义的加载器,实现定制化的方式。
类的唯一性是由类加载器与类的全名两者一同确定的。

链接

指将创建成的类合并至Java虚拟机中,是指能够执行,分为验证、准备、以及解析三个阶段。

  • 验证:确保加载类能够满足Java虚拟机的约束条件。
  • 准备:为被加载类的静态字段分配内存。Java 代码中对静态字段的具体初始化,则在初始化阶段进行。
  • 解析:编译会对一个方法的调用,僧成一个包含方法所在类的名字,目标方法的参数等等信息的符号引用,来指代要调用的方法,解析的目的是把符号引用解析称为真正的引用。如果符号引用触发的是一个未被加载的类的字段或者类或者方法,那么会触发类的加载。但是未必会触发类的链接与初始化。

规范中没有要求了解的过程中完成解析,使用了符号引用,在执行字节码之前需要完成对符号引用的解析。

初始化

静态字段被final所修饰,类型是基本类型,或者字符串,会被编译器编译为常量值,初始化由虚拟机完成。
其他的赋值操作,静态代码块中的代码被编译器置于同一个方法中client中。
初始化 操作是标记为常量值的字段赋值,以及执行clinit的方法执行,虚拟机通过加锁的手段保证clinit方法仅被执行一次。

你可能感兴趣的:(Java基本知识:Java虚拟机是如何加载类的)