• 一行代码干翻 Java 反射?EggG 流式反射调用让反射优雅到不可思议


    你还在写 10 行反射代码只为调一个方法吗?该换个姿势了。

    痛点:Java 反射的"丑陋真相"

    每个 Java 开发者都经历过这种痛苦——当你需要用反射调用一个方法时,画风是这样的:

    Class clazz = Person.class;
    Constructor ctor = clazz.getConstructor(String.class, int.class);
    Object person = ctor.newInstance("Tom", 25);
    Method method = clazz.getMethod("hello");
    method.setAccessible(true);
    String result = (String) method.invoke(person);
    

    6 行代码,只为创建一个对象并调用一个方法。

    这还没完。你还得处理一堆受检异常(NoSuchMethodExceptionIllegalAccessExceptionInvocationTargetException……),精确匹配参数类型(传个 Integer 居然匹配不到 int),手动处理基本类型和包装类型的鸿沟…… 写完之后回头看,满屏的 getDeclaredMethodsetAccessible、强转和 try-catch,代码可读性直接归零。

    这就是 Java 反射几十年来一直被诟病的原因:强大,但丑陋。

    EggG:让反射变成一首诗

    EggGorg.noear:eggg)是 Java 类型元数据分析与构建工具,用一个优雅的链式 API 将反射的复杂度彻底隐藏。

    上面那段 6 行的代码,用 EggG 只需 1 行

    String result = new Eggg().reflect(Person.class)
            .create("Tom", 25)
            .call("hello")
            .get();
    

    就这么简单。没有 getDeclaredMethod,没有 setAccessible,没有强转,没有受检异常。

    四大核心能力,重塑反射体验

    1. 链式调用——代码像说话一样流畅

    EggG 采用 Builder 模式设计,create()call()field()property() 无缝衔接,一行代码完成从创建到调用到取值的完整操作:

    Person person = new Eggg().reflect(Person.class)
            .create()
            .setField("name", "Tom")
            .setField("age", 25)
            .call("hello")          // 调用方法,返回值自动包装
            .get();
    

    void 方法也不怕——调用 void 方法后自动返回原对象包装,链式调用永不中断:

    eggg.reflect(service)
        .call("increment")    // void 方法
        .call("increment")    // 继续链式
        .call("increment");
    

    2. 智能匹配——告别类型精确匹配的噩梦

    传统反射的 getMethod(name, Class...) 要求参数类型精确匹配,传 Integer 不认 int,传 List 不认 Collection

    EggG 内置两级匹配策略:精确匹配 → 模糊匹配自动降级,基本类型与包装类型自动互通:

    // Integer.valueOf(30) 自动匹配 Person(String, int) 的 int 参数
    Person person = eggg.reflect(Person.class)
            .create("Bob", Integer.valueOf(30))
            .get();
    

    方法重载也不再头疼——同名方法按参数自动选择:

    eggg.reflect(dog).call("bark").get();           // "woof"
    eggg.reflect(dog).call("bark", 3).get();        // "woof x3"
    eggg.reflect(dog).call("bark", "hey").get();    // "hey woof"
    

    3. 透明访问——私有成员无需额外处理

    传统反射访问私有成员需要手动 setAccessible(true),而 EggG 做到了完全透明——私有方法、私有字段、私有构造器,统统直接用,框架内部自动处理可见性:

    // 私有方法?直接调用
    String secret = eggg.reflect(obj).call("getSecret").get();
    
    // 私有字段?直接读写
    eggg.reflect(obj).setField("hidden", "revealed");
    

    4. 属性语义——getter/setter 与字段统一抽象

    EggG 提供 property() / setProperty() 语义,优先走 getter/setter,找不到时自动降级为字段访问,一个 API 搞定两种场景:

    // 优先走 setName(),没有则直接设字段
    eggg.reflect(person).setProperty("name", "Alice");
    
    // 优先走 getName(),没有则直接读字段
    String name = eggg.reflect(person).property("name").get();
    

    不止优雅,还有性能

    流式 API 不等于牺牲性能。EggG 在底层做了多重性能优化:

    优化点 说明
    MethodHandle 加速 公有方法自动创建 MethodHandle,调用时优先走 MethodHandle 快速路径,避免反射开销
    元数据软缓存 SoftReference + ConcurrentHashMap 双层缓存,同类只解析一次,内存压力时自动释放
    方法名索引 ClassEggg 内部预建方法名 HashMap 索引,call() 时 O(1) 定位候选方法
    构造器参数快照 ConstrEggg 预存参数别名数组,create() 时高性能匹配

    零依赖,全版本兼容

    • 零依赖:不依赖任何第三方库,加一个 Maven 坐标即可使用
    • 全 JDK 兼容:基于 Java 8 编译,兼容 JDK 8 ~ JDK 25
    • 轻量级:核心代码精简,无侵入性设计
    <dependency>
        <groupId>org.noeargroupId>
        <artifactId>egggartifactId>
        <version>1.1.0version>
    dependency>
    

    对比一览:传统反射 vs EggG

    维度 传统反射 EggG 流式反射
    代码量 5-10 行/操作 1 行链式调用
    类型转换 手动强转 get() 泛型自动转型
    方法匹配 精确类型参数 按名称 + 参数自动匹配
    基本类型/包装类型 不互通 自动互通
    私有成员 手动 setAccessible 透明访问
    void 方法链式 不支持 返回 this,持续链式
    异常处理 多种受检异常 统一 EgggReflectException
    性能加速 MethodHandle + 缓存

    快速上手,5 秒入门

    // 1. 创建 Eggg 实例
    Eggg eggg = new Eggg();
    
    // 2. 从类创建实例 + 调方法
    String result = eggg.reflect(String.class)
            .create("Hello World")
            .call("substring", 6)
            .get();
    // → "World"
    
    // 3. 从已有实例直接调用
    String upper = eggg.reflect("hello")
            .call("toUpperCase")
            .get();
    // → "HELLO"
    
    // 4. 读写字段
    Person p = eggg.reflect(Person.class)
            .create()
            .setField("name", "Tom")
            .get();
    
    // 5. 读写属性(走 getter/setter)
    eggg.reflect(p).setProperty("age", 30);
    int age = eggg.reflect(p).property("age").get();
    

    写在最后

    Java 反射是语言层面赋予开发者的强大能力,但其 API 设计几十年来几乎没有进化。EggG 不是要替代反射,而是要在反射之上,提供一层现代化的流式封装——让反射代码从"必须写"变成"愿意写"。

    如果你正在开发框架、构建插件系统,或者只是厌倦了冗长的反射样板代码,不妨试试 EggG。

    一行链式,胜过十行反射。

  • 相关阅读:
    前端面试HTML和CSS总结,这一篇就够了!
    什么是希尔伯特空间?
    JVM之栈帧解析
    AD脚本使用记录-暂不更新
    【Maven教程】(四)坐标与依赖:坐标概念,依赖配置、范围、传递性和最佳实践 ~
    linux基础:4:gdb的使用
    Linux常用命令
    Java根据线程指标自定义HPA(Prometheus为监控收集)
    力扣刷题(2022-6-28)
    算法笔记(1)线段树
  • 原文地址:https://www.cnblogs.com/noear/p/20209997