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. 子类构造方法

记忆口诀

  • 先静态后实例
  • 先父类后子类
  • 先变量后代码块
  • 先代码块后构造方法
相关推荐
人活一口气4 小时前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP6 小时前
Vibe Coding -- 完整项目案例实操
java
荣码6 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
SimonKing6 小时前
Google第三方授权登录
java·后端·程序员
明月光8186 小时前
从一行 @Builder 说起:重新拾起 Java 的 Lombok、注解与 Builder 模式
java
考虑考虑15 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯16 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路20 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
像我这样帅的人丶你还1 天前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev1 天前
GreenDAO → Room
android·java·kotlin