应用场景

  1. 运行时常量池
  2. 多态的原理
  3. 类加载器的作用
  4. 类的加密和解密

生命周期概述

加载->连接->初始化->使用->卸载

加载阶段

  1. 加载(Loading)阶段第一步时类加载器根据类的全限定名通过不同的渠道(本地文件、动态代理生成、通过网络传输的类)以二进制流的方式来获取字节码信息
    可以使用java代码扩展不同的渠道

  2. 类加载器在加载完类之后,Java虚拟机会将字节码中的信息保存到方法区中
    生成一个InstanceKlass对象 把保存类的所有信息 里面还包含实现特定功能比如多态的信息

  3. 同时Java虚拟机还会在堆中生成一份与方法区中数据类似的java.lang.Class对象
    作用是在Java代码中去获取类的信息以及存储静态字段的数据(JDK8及以后)

  4. 对于开发者来说只需要访问堆中的Class对象而不需要访问方法区中所有信息。
    这样Java虚拟机就能很好地控制开发者访问数据的范围

连接阶段

验证

验证内容是否满足<Java虚拟机规范>

准备

给静态变量赋初值
准备阶段赋的是初始值 与 变量真正在代码中赋的值是不同的(真正赋值的这个步骤在初始化阶段完成)

但如果是final修饰的基本数据类型的静态变量 准备阶段直接会将代码中的值进行赋值

解析

将常量池中的符号引用替换成指向内存的直接引用
直接引用不再使用编号 二是使用内存地址中地址 进行访问具体的数据

初始化阶段

初始化阶段会执行静态代码块中的代码 并为静态变量赋值
初始化阶段会执行字节码文件中clinit部分的字节码指令

题目示例:

直接访问父类的静态变量 不会触发子类的初始化
子类的初始化clinit调用之前 会先调用父类的clinit初始化方法

笔记总结