Java获取Class对象最常用三种方式:类名.class(编译期确定、零开销、不触发初始化)、Class.forName("全限定类名")(动态加载、默认执行静态块)、对象.getClass()(运行时实际类型、需非null实例)。

Java中获取一个类的Class对象,最常用且官方支持的方式就三种,每种对应不同场景,选错容易引发异常或性能问题。
类名.class:编译期确定、零开销
直接用类名加.class,比如 String.class 或 Person.class。它在编译时就校验类是否存在,不触发类加载和静态初始化,JVM直接返回已加载的Class实例。适合框架工具类、泛型擦除后保留类型信息、注解处理器等固定类型场景。
- 不能用于基本类型字面量(如
int.class合法,但5.class语法错误) - 基本类型的包装类可用
.TYPE获取对应基本类型Class,如Integer.TYPE == int.class - 无需异常处理,类型安全,性能最高
Class.forName("全限定类名"):动态加载、可控制初始化
传入字符串形式的完整类名,例如 Class.forName("com.example.User")。JVM会查找并加载该类,**默认执行静态初始化块**。适用于配置驱动、插件化、JDBC驱动注册等运行时才确定类名的场景。
- 必须捕获
ClassNotFoundException - 若只想获取Class元数据、不执行静态块,用重载方法:
Class.forName(name, false, classLoader) - 注意类加载器上下文,避免因ClassLoader不同导致“类已存在却找不到”的问题
对象.getClass():运行时实测、支持多态
调用任意非null对象的getClass()方法,如 new ArrayList().getClass()。它返回对象**实际运行时的类型**,不是声明类型,因此能准确反映继承/代理/泛型擦除后的真身。
立即学习“Java免费学习笔记(深入)”;
- 对象为
null时抛NullPointerException,务必判空 - 无法用于尚未创建实例的类(比如只知接口名,无具体实现)
- 常用于通用序列化、日志打印、类型校验、AOP代理类型识别等
这三种方式覆盖了从编译期到运行时、从静态到动态的全部主流需求。没有一种“万能”,关键是看类信息来源是否已知、是否需要初始化、是否有现成实例。


















