Solon v3.10.7

流式反射调用

</> markdown
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 的基本类型(intlongboolean...)与包装类型(IntegerLongBoolean...)在反射调用中经常引发 NoSuchMethodException。EggG 自动处理这种匹配:

// 构造器声明为 Person(String name, int age)
// 传入 Integer 也能自动匹配 int 参数
Person p = eggg.reflect(Person.class)
    .create("Bob", Integer.valueOf(30))
    .get();

支持的所有基本类型与包装类型自动匹配:

基本类型包装类型
intInteger
longLong
doubleDouble
floatFloat
booleanBoolean
shortShort
byteByte
charCharacter

5、透明访问

EggG 的反射调用自动突破 private 限制,无需手动调用 setAccessible(true)

// 即使 name 是 private 字段也能读写
String name = eggg.reflect(p).field("name").get();
eggg.reflect(p).setField("name", "New Name");

6、异常处理

所有反射异常统一包装为 EgggReflectExceptionRuntimeException 的子类):

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<?>