Class对象

Class对象的创建时间

Class 对象的创建发生在类加载过程的「链接阶段的结束」到「初始化阶段的开始」之间 (主流 HotSpot 虚拟机实现),且一定是在类初始化之前就已创建完成,而非 "加载完后"(加载阶段仅完成二进制字节码加载,尚未形成完整的 Class 对象)。

HotSpot 虚拟机中,Class对象(也叫 "类元信息对象")的创建是加载阶段启动,但链接阶段完成:

  1. 加载阶段 :虚拟机读取字节码后,先在堆内存(注意:方法区存类的运行时数据,Class 对象存堆)创建一个空的 Class 对象雏形,仅记录类的全限定名、父类等基础信息,此时 Class 对象不可用;
  2. 链接阶段(验证 + 准备 + 解析) :虚拟机逐步完善 Class 对象的内容(如静态变量的内存地址、方法的直接引用、接口信息等);
  3. 链接阶段结束后、初始化阶段开始前 :Class 对象完全创建完成,此时可以通过Class.forName()、类名.class等方式获取到这个对象,但类的静态变量还未执行用户指定的赋值(初始化阶段才做)。

方法区存类的运行时数据,Class 对象存堆

java 复制代码
public class ClassObjectTiming {
    // 静态变量(初始化阶段执行赋值)
    public static final String TEST = "初始化完成";

    static {
        System.out.println("执行静态代码块(初始化阶段)");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        // 方式1:通过类名.class获取Class对象(仅触发加载+链接,不触发初始化)
        Class<ClassObjectTiming> clazz1 = ClassObjectTiming.class;
        System.out.println("获取Class对象:" + clazz1.getName());
        System.out.println("此时静态变量值:" + clazz1.getField("TEST").get(null)); // 能获取到默认值/常量值,但未执行静态代码块

        // 方式2:Class.forName(类名, false, 类加载器) ------ false表示不触发初始化
        Class<?> clazz2 = Class.forName("ClassObjectTiming", false, ClassObjectTiming.class.getClassLoader());
        System.out.println("再次获取Class对象:" + clazz2.getName());

        // 方式3:Class.forName(类名) ------ 触发初始化
        Class<?> clazz3 = Class.forName("ClassObjectTiming");
        System.out.println("初始化后获取:" + clazz3.getName());
    }
}
output:
获取Class对象:ClassObjectTiming
此时静态变量值:初始化完成
再次获取Class对象:ClassObjectTiming
执行静态代码块(初始化阶段)
初始化后获取:ClassObjectTiming

常见误区澄清

  1. 误区 1:"加载完就创建 Class 对象"

    → 加载阶段仅生成 Class 对象雏形,链接阶段(验证 / 准备 / 解析)才完成 Class 对象的初始化,加载阶段结束后 Class 对象尚未就绪;

  2. 误区 2:"Class 对象在方法区"

    → HotSpot 中,类的运行时数据(如常量池、方法信息)存在方法区(元空间),但Class对象本身存放在堆内存中;

  3. 误区 3:"获取 Class 对象就等于类初始化"

    → 只有触发《Java 虚拟机规范》中规定的 5 种 "主动使用" 场景(如 new 实例、调用静态方法、反射且不指定不初始化),才会触发初始化,单纯获取 Class 对象(如类名.class)仅触发加载 + 链接。

相关推荐
杨凯凡3 分钟前
Spring Boot 链路追踪实战:Micrometer、TraceId 与异步线程上下文传播
java·spring boot·后端
计算机毕设定制辅导-无忧学长20 分钟前
《基于Spring Boot的迷游哈游戏综合服务平台的开发》
java·vue.js·spring boot·mysql·迷游哈游戏综合服务平台
非优秀程序员9 小时前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻10 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
文丑颜不良啊12 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang13 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪14 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息14 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼14 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff16 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈