Java的类加载

一、什么是类加载时初始化?

类加载时初始化 指的是当Java虚拟机(JVM)第一次加载一个类时,会执行该类的静态成员初始化静态代码块 。这是类生命周期中的一个重要阶段,发生在类被首次使用之前

二、类加载的三个时机

一个类在以下情况下会被加载:

1. 创建类的实例(最常见)

2. 访问类的静态成员

3. 使用反射

三、初始化阶段的具体内容

1. 静态变量的初始化

执行顺序

  1. 先声明所有静态变量(分配内存空间)
  2. 按照代码中的顺序依次初始化静态变量和静态代码块

四、完整的类加载和初始化过程

1. 类加载的三个阶段

详细过程

  1. 加载(Loading)
    • 通过类全限定名找到.class文件
    • 读取字节码到内存
    • 在堆中创建Class对象
  2. 链接(Linking)
    • 验证:检查字节码格式、安全性
    • 准备:为静态变量分配内存,设置默认值
    • 解析:将符号引用转为直接引用
  3. 初始化(Initialization)
    • 执行静态变量赋值
    • 执行静态代码块
    • 执行父类的初始化(如果有)

2.实列展示

五、总结要点

  1. 类加载时初始化是JVM加载类的一个必要阶段
  2. 主要初始化静态成员(静态变量和静态代码块)
  3. 只执行一次(首次使用类时)
  4. 先父类后子类(继承关系)
  5. 与对象创建无关(静态初始化早于对象创建)
  6. 有特定的触发条件和执行顺序

例子:

java 复制代码
class Parent {
    // 父类静态变量
    static {
        System.out.println("父类静态代码块执行");
    }

    static int parentStatic = initParentStatic();

    private static int initParentStatic() {
        System.out.println("父类静态变量初始化");
        return 100;
    }

    // 父类实例变量
    {
        System.out.println("父类构造代码块执行");
    }

    int parentInstance = initParentInstance();

    private int initParentInstance() {
        System.out.println("父类实例变量初始化");
        return 200;
    }

    // 父类构造方法
    public Parent() {
        System.out.println("父类构造方法执行");
    }
}

class Child extends Parent {
    // 子类静态变量
    static {
        System.out.println("子类静态代码块执行");
    }

    static int childStatic = initChildStatic();

    private static int initChildStatic() {
        System.out.println("子类静态变量初始化");
        return 300;
    }

    // 子类实例变量
    {
        System.out.println("子类构造代码块执行");
    }

    int childInstance = initChildInstance();

    private int initChildInstance() {
        System.out.println("子类实例变量初始化");
        return 400;
    }

    // 子类构造方法
    public Child() {
        System.out.println("子类构造方法执行");
    }
}

public class FullInitializationDemo {
    public static void main(String[] args) {
        System.out.println("=== 第一次创建Child对象 ===");
        Child child1 = new Child();
        System.out.println("\n===== 第二次创建Child对象 ===");
        Child child2 = new Child();
    }
}

输出结果

观察

  1. 静态部分只执行一次(第一次加载类时)
  2. 先父类后子类(静态→父类静态→子类静态)
  3. 实例部分每次创建对象都执行

完整顺序

  1. 父类静态变量和静态代码块(按代码顺序)
  2. 子类静态变量和静态代码块(按代码顺序)
  3. 父类实例变量和构造代码块(按代码顺序)
  4. 父类构造方法
  5. 子类实例变量和构造代码块(按代码顺序)
  6. 子类构造方法

记忆口诀

  • 先静态后实例
  • 先父类后子类
  • 先变量后代码块
  • 先代码块后构造方法
相关推荐
用户446139430271 分钟前
从单体到微服务:我们项目的拆分思路和踩坑记录
java
雪碧透心凉_27 分钟前
while 循环与循环嵌套
开发语言·python
TDengine (老段)32 分钟前
TDengine 免费版说明
java·大数据·数据库·物联网·时序数据库·tdengine
乐观勇敢坚强的老彭34 分钟前
信奥C++一维数组笔记
开发语言·c++·笔记
码上有光36 分钟前
异常和智能指针
java·大数据·c++·servlet·异常·智能指针
这就是佬们吗42 分钟前
Python入门⑤-异常处理、文件操作与实战项目
开发语言·数据库·python·算法·pycharm
asdzx671 小时前
Python PDF 拆分实战指南:单页拆分与按需页码范围拆分
开发语言·python·pdf
孬甭_1 小时前
C++ vector
开发语言·c++
学计算机的计算基1 小时前
操作系统内存管理全解:虚拟内存、页表、COW、malloc、OOM一篇搞定
java·笔记·算法
tachibana21 小时前
hot100 前 K 个高频元素(347)
java·数据结构·算法·leetcode