一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Java 反射机制基础:Class 对象获取与动态加载实战

时间:2026-06-24 08:43:46 编辑:袖梨 来源:一聚教程网

Java反射机制的核心起点是获取Class对象,三种方式分别为:类名.class(编译期确定、不触发初始化)、对象.getClass()(运行时获取实际类型、支持多态)、Class.forName("全限定名")(动态加载并执行静态初始化)。

Java 反射机制的核心起点,就是拿到一个类的 Class 对象。它不是普通类的实例,而是 JVM 为每个已加载类在元空间中生成的“结构说明书”。没有它,后续所有动态创建对象、调用方法、访问字段的操作都无从谈起。而动态加载的关键,也正始于如何在运行时拿到这个 Class 对象——类名甚至可能来自配置文件或用户输入。

Class 对象的三种标准获取方式

无论目标类是否已实例化、是否在编译期可见,这三种方式覆盖了绝大多数场景,本质都是指向同一个 Class 实例(JVM 中唯一):

  • 类字面量(.class):编译期已知类,最安全高效。例如 Student.class,不触发类初始化,也不抛异常。
  • 对象.getClass():已有实例时直接获取,类型精准,适用于多态场景。比如 new Student().getClass() 返回的就是 Student 的 Class 对象。
  • Class.forName("全限定名"):运行时按字符串加载类,会触发类的初始化(执行 static 块)。这是实现配置驱动、插件化、动态路由的基础,但需捕获 ClassNotFoundException

动态加载类的典型流程

拿到 Class 对象只是第一步,真正实现“运行时决定用哪个类”,还需完成实例化与方法调用:

  • clazz.getDeclaredConstructor(...).setAccessible(true).newInstance(...) 可绕过访问控制,调用私有构造器;
  • 调用方法前,先通过 clazz.getMethod("methodName", paramTypes)getDeclaredMethod 获取 Method 对象;
  • 静态方法调用时,invoke 的第一个参数传 null;实例方法则传具体对象;
  • 若方法是 private,必须先调用 setAccessible(true) 才能成功执行。

实际应用中的关键细节

反射虽灵活,但容易踩坑,几个常见注意事项要牢记:

立即学习“Java免费学习笔记(深入)”;

  • 数组、基本类型(如 int.class)、void 都有对应的 Class 对象,不能只关注普通类;
  • 泛型在运行时被擦除,List<String>.class 实际等价于 List.class
  • 频繁反射调用性能较低,可缓存 Constructor/Method 对象,避免重复查找;
  • SecurityManager 存在时,setAccessible(true) 可能被拒绝,生产环境需评估权限策略。

为什么框架离不开反射

Spring 的 Bean 初始化、MyBatis 的 SQL 映射绑定、JUnit 的测试方法扫描——它们都不在编译期硬编码类名和方法名。而是靠读取注解、XML 或配置项,再用反射动态加载类、注入属性、调用回调。这种解耦让框架具备高度可扩展性:你写个新 Service,加个 @Service,它就被自动发现并管理,背后全是 Class 对象 + 反射在工作。

热门栏目