概述:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可已被虚拟机直接使用的Java类型,这就是类加载机制。
阶段:加载、验证、准备、解析、初始化、使用、卸载。


类加载的时机

加载可以交给虚拟机的具体实现来自有把握;
初始化的情况

  • 遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,使用new实例化对象的时候、读取或设置一个类的静态字段、调用一个类的静态方法的时候。
  • 使用reflect包的方法对类进行反射调用的时候,如果类没有进行初始化,则需要先触发其初始化;
  • 当初始化一个类的时候,发现其父类还没有初始化,则需要先触发其父类初始化。
  • 当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会初始化这个主类。

接口和类初始化的区别
当一个类在初始化时,要求其父类全部都已经初始化过了,但是一个接口在初始化时,并不要求其父接口全部都完成初始化,只有在真正用到父接口时才会初始化。

类加载过程

加载
方法区(1.7之前叫永久代,从1.8开始叫元空间)

  • 将类的字节码信息加载到元空间(方法区)中,将静态存储结构转换为方法区的运行时数据结构;
  • 并且生成一个java.lang.Class对象,作为方法区这些数据的访问入口;
  • 如果这个类还有父类没加载,则先加载父类;如果在加载过程中,父类被删除,则发生NoClassDefFoundError错误,即没有类定义被找到。
    ClassNotFoundException 类没有被找到异常,发生在类加载阶段,加载类本身不存在;而NoClassDefFoundError是第一个类找到了,跟它关联的类没找到。

注意: 这里的字节码二进制流只并非是从class文件中获取,还有可能从其他地方获取。如网络中、数据库中、运行时计算生成等;

连接阶段

验证

  • 验证类是否符合JVM规范、安全性检查;保证字节码的正确性,不会危害虚拟机自身安全;
    • 文件格式验证:验证字节流是都符合class文件格式的规范;
    • 元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范要求;
    • 字节码验证:保证被校验类的方法在运行时不会做出危害虚拟机安全的行为。
    • 符号引用验证:对类自身以外的信息进行匹配性校验;

准备
类变量(被static修饰的变量) 分配内存并设置类变量初始值阶段,这些内存都将在方法区中进行分配;

解析
将常量池内的符号引用替换为直接引用的过程

初始化

在类初始化之前,会有一个特殊的构造方法,线程安全的,只会执行一次,用来收集所有静态代码块,静态变量的赋值语句操作,按顺序收集。然后以线程安全的方式来执行这个特殊构造;

初始化触发的时机:

  • 首次访问这个类的静态变量或静态方法时;
  • 子类初始化,如果父类还没有还没有,会触发;
  • main方法所在的类,首先被初始化;

不会触发初始化

  • 访问类的static final 变量不会触发初始化,甚至不会触发类的链接;
  • 类对象.class不会触发初始化;
  • 创建该类的数组不会触发初始化;

类加载器

概念:
“通过一个类的全限定名来获取描述此类的二进制字节流“ 把这个动作放到虚拟机外部去实现,以便额昂程序自己决定如何去获取所有的类,实现这个动作的代码被称为类加载器。

类的双亲委派加载机制

  • 启动类加载器:负责加载jdk jre/lib中核心的类,例如:rt.jar,由C++实现,是虚拟机自身的一部分。
  • 扩展类加载器:负责加载jre/lib/ext 扩展目录中的类;
  • 应用程序类加载器(系统类加载器):加载classpath下的所有class类;

注意:从上到下 父亲关系

类的加载顺序:

深入理解Java虚拟机(六) 类加载机制

  • 先找到应用程序类加载器,调用loadClass();
  • 找父亲类加载器即扩展类加载器,看是否类已经被加载;
  • 如果没找到,再委托它的父亲(扩展)再去找启动类(扩展类加载器的父亲)加载器;
  • 如果在再找到就返回,由自己去classPath中找;

如果没有这种委托机制,就有可能造成级别低的类加载器加载更通用的类,其他使用String的代码不能正常工作,像String这种比较通用的类应该由更高级别的类加载去加载;

相关文章:

  • 2021-11-12
  • 2021-10-12
  • 2021-10-04
  • 2021-06-08
  • 2021-08-30
  • 2021-12-04
  • 2021-10-22
  • 2021-04-14
猜你喜欢
  • 2021-04-11
  • 2021-10-17
  • 2021-10-09
  • 2022-01-10
  • 2021-08-09
  • 2021-09-22
  • 2021-04-08
相关资源
相似解决方案