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

Java中是否有类似C# Action的功能可监听指定方法调用?

Java实现类方法调用监听的方案

Java没有内置和C# Action 完全一致的语法糖,但可以通过函数式接口+回调集合的方式实现完全等效的能力,针对不同场景有两种常用实现方案:

1. 侵入式实现(推荐,逻辑和C# Action完全对齐)

该方案需要修改目标类的源码,和C# Action的使用逻辑几乎一致,性能最优、上手最简单:

  1. 在目标类中定义List<Consumer<T>>类型的集合存储所有注册的回调,T为回调触发时要传递的参数类型(比如你要传递触发方法的实例,就填目标类的类型)
  2. 对外提供注册回调的方法
  3. 在需要监听的目标方法的对应位置,遍历回调集合逐个触发

代码示例

目标类实现:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class TargetClass {
    // 回调集合,泛型参数为触发回调时传递的参数类型,这里传递当前实例
    private final List<Consumer<TargetClass>> targetMethodListeners = new ArrayList<>();
    private String id;

    public TargetClass(String id) {
        this.id = id;
    }

    // 注册回调的方法
    public void addTargetMethodListener(Consumer<TargetClass> listener) {
        if (listener != null) {
            targetMethodListeners.add(listener);
        }
    }

    // 需要监听的目标方法
    public void targetMethod() {
        // 目标方法的原有业务逻辑
        // ...

        // 触发所有注册的回调,等效于C#中Action.Invoke
        for (Consumer<TargetClass> listener : targetMethodListeners) {
            listener.accept(this);
        }
    }

    public String getId() {
        return id;
    }
}

集合实例监听使用示例:

import java.util.ArrayList;
import java.util.List;

public class ListenerTest {
    public static void main(String[] args) {
        // 你的ArrayList实例集合
        List<TargetClass> instanceList = new ArrayList<>();
        instanceList.add(new TargetClass("实例1"));
        instanceList.add(new TargetClass("实例2"));

        // 给每个实例注册回调
        for (TargetClass instance : instanceList) {
            instance.addTargetMethodListener(triggerInstance -> {
                System.out.println("触发方法的实例ID:" + triggerInstance.getId());
                // 你的回调逻辑
            });
        }

        // 调用实例1的目标方法,会触发对应的回调
        instanceList.get(0).targetMethod();
    }
}

如果需要传递多个自定义参数,可以自行定义函数式接口替换Consumer即可;如果需要多线程场景下使用,可将回调集合替换为线程安全的CopyOnWriteArrayList

2. 无侵入实现(无需修改目标类源码)

如果无法修改目标类的源码,可以通过动态代理对目标实例做包装,拦截指定方法的调用后触发回调:

  • 如果目标类实现了接口,可以用JDK自带的动态代理实现
  • 如果目标类没有实现接口,可以引入CGLIB库做类代理实现
  • 如果是Spring项目,可以直接用AOP切点匹配指定方法,统一处理监听逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:54:07