Java反射需理解Class对象原理并动手实践:Class是反射唯一入口,获取方式有类名.class、对象.getClass()、Class.forName();核心API包括Field、Method、Constructor;注意异常处理、setAccessible()限制、缓存优化及真实场景练手。

Java 反射不是靠背概念就能掌握的,关键是在理解原理的基础上,动手拆解、验证、封装常用操作。所谓“备战”,不是临时抱佛脚,而是建立一套可复用、易调试、能应对面试和框架源码阅读的反射能力体系。
搞懂 Class 对象:反射唯一的入口
所有反射操作都从 Class 对象开始——它不是你写的类,而是 JVM 加载 .class 文件后在内存中生成的“类的镜像”。它唯一、不可变,包含全部结构信息(字段、方法、构造器、注解、修饰符等)。
获取方式就三种,各用在不同场景:
-
类名.class:编译期已知类型,最安全高效,比如
User.class; - 对象.getClass():已有实例,想查它的实际运行时类型(注意可能和声明类型不同,如子类对象赋给父类引用);
-
Class.forName("全限定名"):运行时动态加载,配置驱动、插件化、JSON 序列化库都靠它,比如
Class.forName("com.example.OrderService")。
用好核心 API:Field、Method、Constructor
拿到 Class 对象后,真正干活的是 java.lang.reflect 包里的三个主力:
立即学习“Java免费学习笔记(深入)”;
-
Field:读写属性,包括 private 字段(需先调用
setAccessible(true)); -
Method:调用任意方法(public/private/static),注意参数类型要严格匹配,比如
getDeclaredMethod("setId", int.class); -
Constructor:创建对象,支持无参/有参构造,私有构造也能用(同样要
setAccessible(true))。
小技巧:用 getDeclaredXXX() 获取本类定义的所有成员(含 private),用 getXXX() 只获取 public 成员(含继承来的)。
实战中绕不开的几个关键点
光会调 API 不代表真会用反射,这些细节决定代码是否健壮:
- 反射调用方法或访问字段前,务必处理 IllegalAccessException 和 InvocationTargetException;
- 调用私有成员必须显式设为可访问,但 JDK 9+ 模块系统下可能被限制,生产环境慎用;
-
Class.newInstance()已废弃,统一改用Constructor.newInstance(); - 大量反射操作有性能开销,高频场景建议缓存 Method 或 Field 对象,避免重复查找。
结合真实场景练手才记得牢
别只写 “Hello Reflect”,试试这几个贴近实际的小任务:
- 写一个通用的 对象复制工具:把 source 对象的同名 public 字段值拷贝到 target 对象;
- 模拟 Spring Bean 初始化:根据类名字符串加载类 → 调用无参构造 → 扫描 @Autowired 字段 → 注入依赖;
- 解析一个实体类上的 @Table 和 @Column 注解,生成建表 SQL 片段;
- 用反射调用一个私有工具方法,验证它是否真能绕过访问控制。
每完成一个,回头看看 Class 是怎么拿到的、Field 是怎么定位的、异常是怎么捕获的——知识就落地了。


















