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

记忆口诀:

  • 先静态后实例
  • 先父类后子类
  • 先变量后代码块
  • 先代码块后构造方法
相关推荐
一晌小贪欢10 分钟前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
xiaoye-duck42 分钟前
《C++ 项目:手写大模型接入 SDK》LLMManager架构设计与实现
开发语言·网络·c++·语言模型
一条大祥脚1 小时前
CuTe 与 CuTe DSL:从 C++ 模板元编程到 Python DSL 的 GPU 编程演进
开发语言·c++·python·cutlass·cute·cute dsl
学长毕设1 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
FRing032 小时前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
旖旎夜光2 小时前
【C++ 基础入门】C++ 多态(上):虚函数、重写、override/final 与抽象类
开发语言·c++·笔记·学习
SL_staff2 小时前
离散制造排程破局:JVS-APS 四步闭环落地实践(开发者视角)
java·产品·全栈
这个昵称不容易2 小时前
SpringBoot 美容院管理系统:232个Java文件315个接口,5套角色从预约到发货一整条链路
java·springboot·毕设
starzy19902 小时前
深入理解Scala嵌套函数:作用域封装之道
开发语言·scala
Sakura_j_h_2 小时前
从零写一个 MCP stdio Server:用 Python 校验博客文章格式
开发语言·python·自动化·ai工具·mcp·json-rpc