java反射获取class对象有三种核心方式:类名.class最安全高效,适用于编译期已知类型;class.forname()支持动态加载并可选初始化,适合配置驱动场景;obj.getclass()用于运行时实例外观推导,依赖对象存在。

Java 反射机制中获取 Class 对象,核心就三种方式,各自适用不同阶段和需求,选错容易引发异常或性能问题。
类名.class:编译期已知类型时最稳最快
直接用类型名加 .class,比如 String.class、User.class。它不触发类加载或静态初始化,也不抛异常,JVM 直接返回已加载的 Class 实例。适合工具类、泛型处理、注解处理器等对类型确定性要求高的场景。
- 无需异常捕获,零运行时开销
- 不能用于动态类名(比如配置里读出来的字符串)
- 返回的是编译期声明类型,不是运行时实际类型(这点和
getClass()不同)
对象.getClass():已有实例时精准获取实际类型
调用任意对象的 getClass() 方法,例如 new ArrayList<string>().getClass()</string> 返回的是 ArrayList 而非 List。它反映的是运行时真实类,天然支持多态,在通用序列化、日志打印、类型校验中很实用。
- 必须确保对象已创建,空指针会直接报
NullPointerException - 无法用于“先建模后实例化”的流程(比如还没 new 出来就要操作类结构)
- 返回的 Class 对象与
类名.class完全一致(JVM 中同一个类只有一份 Class 实例)
Class.forName("全限定名"):运行时按字符串加载类
传入字符串形式的完整类名,如 Class.forName("java.util.Date")。这是实现插件化、配置驱动、JDBC 驱动注册等动态能力的基础。默认会触发类的初始化(执行 static 块),若只想获取元信息而不执行初始化,可用带参数的重载:Class.forName(name, false, classLoader)。
- 必须捕获
ClassNotFoundException - 类名拼错、类路径缺失、访问权限不足都会导致失败
- 适用于类名来自配置文件、用户输入、网络响应等不确定来源的场景
这三种方式最终指向 JVM 元空间中同一个 Class 实例,区别只在获取时机、安全性与灵活性。用哪一种,取决于你手上有什么信息:是写死的类型?已有对象?还是一个字符串?
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











