Class对象是JVM为每个类生成的唯一元数据载体,代表其结构与运行时身份;它非普通实例,而是java.lang.Class类型对象,是反射入口、类型系统基石,生命周期绑定类加载器。

Class对象是Java运行时系统为每个类(包括接口、枚举、数组、基本类型、void)自动生成的唯一元数据载体,它代表该类本身的结构信息和运行时身份。 它不是你用new创建出来的普通实例,而是JVM在类加载阶段自动创建并维护的“类的类”——即java.lang.Class类型的对象。
Class对象从哪来?三种常见获取方式
每个类在运行时都对应且仅对应一个Class对象。获取它的常用途径有:
-
类名.class:最直接,编译期确定,无性能开销。例如:
String.class、int.class、void.class; -
实例.getClass():通过已有对象反查其运行时真实类型,适用于多态场景。例如:
new ArrayList().getClass()返回ArrayList.class; -
Class.forName("全限定类名"):动态加载类,触发类初始化(执行static块),常用于配置驱动、插件机制等。例如:
Class.forName("com.example.User")。
Class对象是反射机制的入口
所有反射操作都始于一个Class对象。它提供了访问类结构的完整API:
- 获取构造器:
getConstructor()、getDeclaredConstructors(); - 获取方法:
getMethod("name", paramTypes)、getDeclaredMethod(); - 获取字段:
getField("name")、getDeclaredField(); - 判断类型关系:
isAssignableFrom()、isInstance()、isArray()、isInterface(); - 获取泛型信息:
getTypeParameters()、getGenericSuperclass()。
没有Class对象,就无法在运行时探知类的成员、调用私有方法或绕过编译检查——反射的本质就是基于Class对象的元数据操作。
立即学习“Java免费学习笔记(深入)”;
Class对象是JVM类型系统的基石
JVM靠Class对象区分不同类加载器加载的同名类(如Web应用中多个ClassLoader加载的org.apache.commons.lang.StringUtils),也靠它实现类型安全校验:
- 每次
new、类型转换(cast)、instanceof判断,JVM都在底层比对目标对象的Class是否与期望类型一致; - 泛型擦除后,运行时仍需
Class对象参与类型检查(如ArrayList和ArrayList在运行时共享同一个Class对象,但元素类型由泛型签名+Class共同约束); - 数组类型也有对应的
Class对象:int[].class、String[][].class,它们与组件类型相关联,但不继承自Object.class。
Class对象的生命周期与类加载器绑定
一个Class对象的生命周期严格跟随其所属的类加载器:
- 类加载器负责定义类(defineClass)、链接(link)和初始化(initialize),并生成唯一的
Class对象; - 同一类被不同类加载器加载,会得到两个不同的
Class对象,彼此不兼容(即使全名相同,也不能互相赋值或转型); - 当类加载器被回收且无其他强引用指向其加载的
Class对象时,这些Class对象才可能被GC回收(需满足所有实例也被回收、无静态引用等条件)。
这解释了为什么OSGi、Spring Boot DevTools、Tomcat热部署等场景必须精细管理类加载器——本质是在管理Class对象的可见性与生命周期。










