流式反射调用
2026年5月29日 上午8:55:00
用一行链式调用替代传统反射的多行代码,同时统一了异常处理。
1、对比
传统反射写法
try {
Class<?> clazz = Class.forName("com.example.Person");
Constructor<?> ctor = clazz.getConstructor(String.class, int.class);
Object obj = ctor.newInstance("Tom", 25);
Method method = clazz.getMethod("sayHello");
Object result = method.invoke(obj);
} catch (ClassNotFoundException | NoSuchMethodException |
InstantiationException | IllegalAccessException |
InvocationTargetException e) {
throw new RuntimeException(e);
}
EggG 写法
String result = eggg.reflect(Person.class)
.create("Tom", 25)
.call("sayHello")
.get();
传统写法需要 6 行代码并处理 5 种受检异常,EggG 将其简化为 1 行,异常统一为 EgggReflectException。
2、核心 API
Eggg.reflect() — 入口方法
从类或实例开始创建流式反射链:
// 从类开始(需要先 create 创建实例)
EgggReflect reflect = eggg.reflect(Person.class);
// 从实例开始(直接操作现有对象)
EgggReflect reflect = eggg.reflect(personInstance);
create() — 创建实例
从 Class 创建对象实例:
// 无参构造
Person p = eggg.reflect(Person.class).create().get();
// 有参构造(基本类型自动互通)
Person p = eggg.reflect(Person.class).create("Tom", 25).get();
call() — 调用方法
调用指定名称的方法:
// 无参方法
String result = eggg.reflect(person).call("sayHello").get();
// 有参方法
String result = eggg.reflect("Hello World").call("substring", 6).get();
// 静态方法
String result = eggg.reflect(Person.class).call("staticHello").get();
field() / setField() — 字段读写
直接读写字段值,绕过 getter/setter:
// 字段写
Person p = eggg.reflect(Person.class)
.create()
.setField("name", "Tom")
.setField("age", 25)
.get();
// 字段读
String name = eggg.reflect(p).field("name").get(); // "Tom"
property() / setProperty() — 属性读写
通过 getter/setter 方法读写属性:
// 属性写(调用 setName()、setAge())
Person p = eggg.reflect(Person.class)
.create()
.setProperty("name", "Alice")
.setProperty("age", 30)
.get();
// 属性读(调用 getName())
String name = eggg.reflect(p).property("name").get(); // "Alice"
get() — 获取结果
链式调用的终点,返回当前持有的对象:
Person p = eggg.reflect(Person.class).create().get();
String name = eggg.reflect(p).field("name").get();
3、链式调用模式
EgggReflect 采用 Builder 模式设计,所有操作都返回 EgggReflect 自身,支持无限链式调用。
以下示例演示了用户注册流程中的动态对象创建:
User user = eggg.reflect(User.class) // 1. 指定 User 类
.create("Tom", 25) // 2. 调用构造器创建实例
.setField("email", "tom@test.com") // 3. 直接设置 private 字段
.setProperty("role", "admin") // 4. 通过 setter 设置角色
.call("initPermissions") // 5. 调用初始化方法
.get(); // 6. 获取结果
4、基本类型自动互通
Java 的基本类型(int、long、boolean...)与包装类型(Integer、Long、Boolean...)在反射调用中经常引发 NoSuchMethodException。EggG 自动处理这种匹配:
// 构造器声明为 Person(String name, int age)
// 传入 Integer 也能自动匹配 int 参数
Person p = eggg.reflect(Person.class)
.create("Bob", Integer.valueOf(30))
.get();
支持的所有基本类型与包装类型自动匹配:
| 基本类型 | 包装类型 |
|---|---|
int | Integer |
long | Long |
double | Double |
float | Float |
boolean | Boolean |
short | Short |
byte | Byte |
char | Character |
5、透明访问
EggG 的反射调用自动突破 private 限制,无需手动调用 setAccessible(true):
// 即使 name 是 private 字段也能读写
String name = eggg.reflect(p).field("name").get();
eggg.reflect(p).setField("name", "New Name");
6、异常处理
所有反射异常统一包装为 EgggReflectException(RuntimeException 的子类):
try {
String result = eggg.reflect(obj).call("someMethod").get();
} catch (EgggReflectException e) {
// 所有反射异常统一在此处理
log.error("反射调用失败", e);
}
7、性能优化
| 优化手段 | 说明 |
|---|---|
| MethodHandle 加速 | 公有方法使用 MethodHandle 调用,比传统 Method.invoke() 更快 |
| 方法名索引 | 按方法名建立索引,避免每次全量遍历 |
| 构造器参数快照 | 预计算构造器参数类型,加速匹配 |
| 软引用缓存 | TypeEggg / ClassEggg 使用软引用缓存,内存紧张时自动释放 |
8、完整示例
public class FluentReflectDemo {
private static final Eggg eggg = new Eggg();
public static void main(String[] args) {
// 1. 从类创建实例
String result1 = eggg.reflect(String.class)
.create("Hello World")
.call("substring", 6)
.get();
System.out.println(result1); // "World"
// 2. 从实例直接调用
String result2 = eggg.reflect("Hello World")
.call("substring", 6)
.get();
System.out.println(result2); // "World"
// 3. 字段读写
Person person = eggg.reflect(Person.class)
.create()
.setField("name", "Tom")
.setField("age", 25)
.get();
String name = eggg.reflect(person)
.field("name")
.get(); // "Tom"
// 4. 属性读写(通过 getter/setter)
Person p = eggg.reflect(Person.class)
.create()
.setProperty("name", "Alice")
.setProperty("age", 30)
.get();
String pName = eggg.reflect(p)
.property("name")
.get(); // "Alice"
// 5. 调用静态方法
String s = eggg.reflect(Person.class)
.call("staticHello")
.get();
// 6. 基本类型自动互通
Person p2 = eggg.reflect(Person.class)
.create("Bob", 30)
.get();
}
}
9、API 速查
| 方法 | 说明 | 返回值 |
|---|---|---|
reflect(Class<?>) | 从类开始 | EgggReflect |
reflect(Object) | 从实例开始 | EgggReflect |
create(Object...) | 创建实例 | EgggReflect |
call(String, Object...) | 调用方法 | EgggReflect |
field(String) | 读取字段 | EgggReflect |
setField(String, Object) | 写入字段 | EgggReflect |
property(String) | 读取属性(getter) | EgggReflect |
setProperty(String, Object) | 写入属性(setter) | EgggReflect |
get() | 获取当前对象 | <T> T |
type() | 获取当前类型 | Class<?> |