You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现无需反射/Invoke跨类调用监听器并返回指定类型?

实现无反射的监听器调用机制

1. 定义匹配方法签名的函数式接口

先创建一个函数式接口,匹配你需要调用的方法签名(接收CanCreatureAttack参数,返回ListenerReturn),这样就能直接用方法引用注册,完全避开反射:

@FunctionalInterface
public interface CreatureAttackListener {
    ListenerReturn canCreatureAttack(CanCreatureAttack context);
}

2. 实现全局静态监听器容器

用一个线程安全的Map存储监听器实例,提供注册和执行的静态方法:

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ListenerContainer {
    private static final Map<String, CreatureAttackListener> LISTENER_MAP = new ConcurrentHashMap<>();

    // 注册监听器,key用自定义标识(比如类名)
    public static void register(String key, CreatureAttackListener listener) {
        LISTENER_MAP.put(key, listener);
    }

    // 执行监听器并返回结果
    public static ListenerReturn execute(String key, CanCreatureAttack context) {
        CreatureAttackListener listener = LISTENER_MAP.get(key);
        return listener != null ? listener.canCreatureAttack(context) : new ListenerReturn(false);
    }
}

3. 改造自定义类并完成注册

修正原类的语法错误,在构造方法中通过方法引用把当前类的逻辑注册到容器:

public class MyCustomClass {
    public MyCustomClass() {
        // 注册当前类的canCreatureAttack方法,key指定为"myClassName"
        ListenerContainer.register("myClassName", this::canCreatureAttack);
    }

    public ListenerReturn canCreatureAttack(final CanCreatureAttack canCreatureAttack) {
        // 修正语法错误:isSuperPlayer后多了括号,ListenerReturn首字母大写
        if (canCreatureAttack.getAttacker().isSuperPlayer()) {
            return new ListenerReturn(true);
        }
        // 统一返回ListenerReturn类型,不能直接返回boolean
        return new ListenerReturn(false);
    }
}

4. 调用监听器的示例

确保MyCustomClass已实例化(构造方法会自动完成注册),之后直接调用容器方法即可:

// 初始化自定义类,自动注册监听器
new MyCustomClass();

// 构造参数并调用监听器
CanCreatureAttack attackContext = new CanCreatureAttack(actor, target);
// 注意:return是Java关键字,不能用作变量名
final ListenerReturn result = ListenerContainer.execute("myClassName", attackContext);

核心说明

  • 这套方案用函数式接口+方法引用替代反射,本质是把方法转换成接口实例存储,调用时直接执行接口方法,完全不需要反射API。
  • 如果需要支持多种类型的监听器,可以定义多个函数式接口,或者用泛型扩展容器的通用性。
  • 容器的key可以根据需求调整,比如用类的全限定名、枚举值等,只要保证唯一即可。

内容的提问来源于stack exchange,提问作者Clean code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:40:38