反射是让java程序在运行时能动态感知并操作类结构的能力,核心是class对象,本质是弥补编译期类型信息固定带来的局限,支撑spring、mybatis等框架实现动态实例化、方法调用与字段访问。

面试时讲反射,别堆术语,重点说清它“为什么存在”和“解决什么问题”。一句话概括:反射是让Java程序在运行时能动态感知并操作类结构的能力,核心是Class对象,本质是弥补编译期类型信息固定带来的局限。
反射的定义:从“写死代码”到“运行时才知道”
正常Java开发中,类、方法、字段在编译期就完全确定,比如 User user = new User(),编译器必须看到User类才能通过。而反射把这件事推迟到运行期:你只有一串字符串(如"com.example.User"),程序加载它、查它的字段、调用它的私有方法、甚至创建实例——所有操作都在JVM跑起来之后发生。
这就像平时按菜单点菜(编译期定死),反射则是走进后厨现场清点食材、看厨师名单、再决定怎么做(运行期动态探知)。
核心作用:支撑通用框架的底层能力
框架无法预知用户写的类,但又要统一处理——反射正是这个桥梁:
-
动态实例化:Spring读取
@Component或XML里的类名,用Class.forName()加载,再通过Constructor.newInstance()创建Bean,不用硬编码new UserService() -
动态方法调用:SpringMVC匹配完请求路径,靠
Method.invoke()执行Controller方法;MyBatis把数据库结果集映射到实体类,靠反射给私有字段赋值 -
动态访问成员:JUnit测试private方法、Lombok生成的getter/setter底层读写字段、Jackson序列化跳过访问修饰符直接操作
field.set()
必须点明的分寸感:灵活≠万能
面试官想听你有没有工程意识,所以顺带提一句代价:
- 性能损耗:每次
invoke或set都含安全检查、类型转换、栈帧开销,比直接调用慢5–10倍 - 封装性削弱:可读私有字段、调用private方法,虽方便框架实现,但也绕过设计约束,部分Android环境或安全沙箱会禁用
- API易错:比如
getDeclaredMethod()和getMethod()区别、参数类型要精确匹配(int.class不能写Integer.class)、私有成员需先setAccessible(true)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











