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

相关推荐
Wang15304 小时前
jdk内存配置优化
java·计算机网络
0和1的舞者4 小时前
Spring AOP详解(一)
java·开发语言·前端·spring·aop·面向切面
Wang15305 小时前
Java多线程死锁排查
java·计算机网络
小小星球之旅5 小时前
CompletableFuture学习
java·开发语言·学习
jiayong236 小时前
知识库概念与核心价值01
java·人工智能·spring·知识库
皮皮林5516 小时前
告别 OOM:EasyExcel 百万数据导出最佳实践(附开箱即用增强工具类)
java
Da Da 泓6 小时前
多线程(七)【线程池】
java·开发语言·线程池·多线程
To Be Clean Coder7 小时前
【Spring源码】getBean源码实战(三)
java·mysql·spring
Wokoo77 小时前
开发者AI大模型学习与接入指南
java·人工智能·学习·架构
电摇小人7 小时前
我的“C++之旅”(博客之星主题作文)
java·开发语言