Java反射获取Class对象有三种方式:一是类名.class,编译期确定、不触发初始化;二是对象.getClass(),运行时获取实际类型、支持多态;三是Class.forName("全限定名"),动态加载并执行静态初始化。

Java反射的起点是获取Class对象。它不是你手动new出来的,而是JVM在类加载时自动创建的唯一元数据载体。掌握三种获取方式,关键在于理解它们所处的生命周期阶段和适用场景。
方式一:类名.class —— 编译期确定,最直接安全
这是编译时就能确认类型的写法,不触发类初始化,性能高、无异常风险。适用于你已知具体类型且无需动态加载的场景,比如工具方法参数、泛型边界、注解处理器中固定类型的处理。
-
String.class 得到
Class<String>,类型安全,支持泛型推导 - int.class 和 Integer.TYPE 等价,但 Integer.class 表示包装类本身
- 基本类型(如
boolean、void)也有对应的.class,例如void.class
方式二:对象.getClass() —— 运行时实测,支持多态
通过已有实例调用,返回该对象**实际运行时类型**的Class对象。它体现的是“是什么”,而不是“声明为什么”,是实现类型判断、通用序列化、日志打印等逻辑的基础。
- 若
Object obj = new ArrayList<>();,则obj.getClass()返回ArrayList.class,不是Object.class - 不能用于基本类型值(如
42.getClass()报错),需先装箱或改用int.class - 空对象调用会抛
NullPointerException,使用前建议判空
方式三:Class.forName("全限定类名") —— 动态加载,配置驱动
字符串驱动,由JVM按需加载类并完成初始化(执行static块)。这是实现插件化、框架扩展、配置驱动的核心机制,比如JDBC驱动注册、Spring Bean按名加载、ORM映射类解析。
立即学习“Java免费学习笔记(深入)”;
- 必须传入完整包路径,如
"java.util.HashMap",否则抛ClassNotFoundException - 会触发类的**静态初始化块**执行,这点区别于前两种方式
- 常配合配置文件、数据库字段或用户输入使用,注意校验与异常兜底
三种方式没有绝对优劣,选哪个取决于你手上的信息:有类?用.class;有实例?用getClass();只有类名字符串?就用forName()。


















