java动态获取class对象有三种方式:类字面量user.class(不触发初始化,编译期校验安全)、class.forname("全限定类名")(触发初始化,需捕获classnotfoundexception)、对象.getclass()(返回实际运行时类型,对象不可为null)。

Java 中动态获取类的 Class 对象是反射操作的第一步,也是最关键的起点。它不依赖编译期已知类型,而是在运行时按需加载并确认类结构。核心方式就三种,适用场景各不相同,选错会影响类初始化行为和异常处理。
类字面量 Class.forName("全限定类名")
这是最常用、也最灵活的方式,适用于配置驱动、插件系统或从字符串(如配置文件、数据库)读取类名的场景。它会触发类的初始化——执行静态代码块和静态字段赋值。
- 必须捕获
ClassNotFoundException异常 - 例如:
Class> clazz = Class.forName("com.example.User"); - 注意:JDK 9+ 模块环境下,若目标类所在包未被导出,会直接抛
NoClassDefFoundError,需配合--add-opens参数或模块声明
类名.class(推荐用于编译期已知类型)
写法最简洁,性能最好,且不会触发类初始化(静态块不执行)。适合工具类、泛型边界、注解处理器等对类结构有静态依赖的场景。
- 无需异常处理,编译期校验安全
- 例如:
Class<user> clazz = User.class;</user> - 注意:不能用于运行时才确定的字符串类名,也不适用于泛型类型擦除后的动态判断
对象实例调用 .getClass()
当你已经有一个对象实例,想反查它的实际运行时类型(尤其涉及多态或子类重写时),这是最直接的方式。它返回该实例真实所属类的 Class 对象,而非声明类型。
- 不会抛
ClassNotFoundException,但对象不能为null(否则空指针) - 例如:
User user = new Admin(); Class> clazz = user.getClass(); // 返回 Admin.class,不是 User.class - 注意:它会触发该类的完整初始化(包括静态块、构造块、构造方法)
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











