反射就像代码的「X光机」,它能让你在程序运行时「透视」类的内部结构,并动态操作对象,即使这些类在写代码时还不存在!
反射能做什么?
-
透视类结构
-
查看类有哪些方法、字段、构造方法。
-
示例:
Class<?> clazz = Class.forName("com.example.User"); Method[] methods = clazz.getDeclaredMethods(); // 获取所有方法
-
-
动态创建对象
-
即使没有
new关键字,也能实例化对象。 -
示例:
Constructor<?> constructor = clazz.getConstructor(String.class, int.class); Object user = constructor.newInstance("张三", 25); // 相当于 new User("张三", 25)
-
-
调用私有方法
-
突破封装,强制调用类的隐藏方法。
-
示例:
Method secretMethod = clazz.getDeclaredMethod("privateMethod"); secretMethod.setAccessible(true); // 暴力破解访问权限 secretMethod.invoke(user);
-
-
修改字段值
-
直接修改对象中的属性(包括私有属性)。
-
示例:
Field field = clazz.getDeclaredField("age"); field.setAccessible(true); field.set(user, 30); // 把 age 改成30
-
反射的常见用途
- 框架开发:比如Spring通过反射创建Bean、注入依赖。
- 动态代理:AOP(面向切面编程)的实现基础。
- IDE功能:比如IDEA的代码自动提示、调试器查看对象信息。
- 插件系统:动态加载外部jar包中的类。
反射的优缺点
| 优点 | 缺点 |
|---|---|
| 灵活性强(动态操作类) | 性能差(比直接调用慢) |
| 突破封装(访问私有成员) | 代码可读性降低 |
| 支持通用代码(如JSON序列化) | 安全隐患(可绕过权限检查) |
反射核心API速览
| 类/方法 | 作用 |
|---|---|
Class.forName("类全名") | 根据类名获取Class对象 |
clazz.newInstance() | 创建实例(已过时,推荐用构造器) |
clazz.getMethod("方法名") | 获取方法 |
method.invoke(对象) | 调用方法 |
field.set(对象, 值) | 修改字段值 |
一句话总结
「反射让代码拥有「透视眼」,运行时动态摸清类底细
灵活强大框架基,性能安全要注意!」