Java中是否有类似C# Action的功能可监听指定方法调用?
Java实现类方法调用监听的方案
Java没有内置和C# Action 完全一致的语法糖,但可以通过函数式接口+回调集合的方式实现完全等效的能力,针对不同场景有两种常用实现方案:
1. 侵入式实现(推荐,逻辑和C# Action完全对齐)
该方案需要修改目标类的源码,和C# Action的使用逻辑几乎一致,性能最优、上手最简单:
- 在目标类中定义
List<Consumer<T>>类型的集合存储所有注册的回调,T为回调触发时要传递的参数类型(比如你要传递触发方法的实例,就填目标类的类型) - 对外提供注册回调的方法
- 在需要监听的目标方法的对应位置,遍历回调集合逐个触发
代码示例
目标类实现:
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
相关产品推荐
相关产品推荐

