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)仅触发加载 + 链接。

相关推荐
zhanghaha13141 小时前
HTML系列教程:14_HTML 表单与输入框 <form>、<input> 零基础详解
java·前端·javascript
yxlalm6 小时前
Spring AI+RAG 01-项目背景与技术选型
java·人工智能·spring
程序员清风7 小时前
Java 后端高并发设计:线程池、限流、熔断与降级
java·数据库·oracle
Seoyoneh8 小时前
Agentic Workflow编排架构:云客服从“被动响应”迈向“主动执行”的技术实现
java·开发语言·架构
海南java第二人8 小时前
对外 API 如何保证幂等性?插入数据 / 上传表格场景全方案汇总
java·幂等性
tryxr8 小时前
Chat2Excel 文件服务模块上传文件功能开发
java·项目·oss·easyexcel·文件服务
Tangyuewei8 小时前
Java 写 Agent:模型只是组件
java·开发语言
彧azz9 小时前
Java学习语法篇:变量
java·学习
信誓旦旦的程序猿10 小时前
【量化系统从零构建 #04】存储设计:选型·建库·交易日历
java·人工智能·python·股票数据api·股票数据·股票数据api接口·股票api数据接口
yurenpai(27届找实习中)10 小时前
Java 10 的 var 为什么不能随便用?从订单汇总看懂类型推断与泛型陷阱
java·开发语言·java18