Java中可用泛型+接口+ConcurrentHashMap+CopyOnWriteArrayList实现类型安全事件总线:以Class为key隔离事件类型,运行时校验投递,支持继承匹配。

Java 中可以用泛型 + 接口 + Map + 线程安全容器实现一个轻量、类型安全的事件监听总线(Event Bus),核心是让不同事件类型(Event<t></t>)和监听器(EventListener<t></t>)通过泛型绑定,避免强制转换和运行时类型错误。
定义泛型事件与监听器接口
先约定事件载体和监听行为,用泛型明确事件数据的类型:
// 事件基类,携带泛型数据
public class Event<T> {<br>
private final T data;<br>
public Event(T data) { this.data = data; }<br>
public T getData() { return data; }<br>
}
// 监听器函数式接口,接收对应类型的 Event
public interface EventListener<T> {<br>
void onEvent(Event<T> event);<br>
}
用 Class> 作 key 实现类型隔离的监听器注册
不能直接用 Class<t></t> 作泛型参数注册(类型擦除),但可用 Class> 对象作为 Map 的 key,保证每种事件类型有独立监听器列表:
- 使用
ConcurrentHashMap<class>, CopyOnWriteArrayList<eventlistener>>></eventlistener></class>存储监听器,兼顾并发安全与遍历时不抛ConcurrentModificationException - 注册时传入事件数据的实际 Class(如
String.class),用于后续精准分发 - 监听器存入时做「类型擦除友好」的存储:用
EventListener>统一接收,靠调用时的显式类型转换 + 泛型约束保障安全
发布事件时做运行时类型校验与安全投递
发布事件时,根据 event.getData().getClass() 或显式传入的 Class<t></t> 查找监听器,并用 instanceof 或 Class.isInstance() 做二次校验,防止误投:
立即学习“Java免费学习笔记(深入)”;
public <T> void post(Event<T> event) {<br>
Class<T> eventType = (Class<T>) event.getData().getClass(); // 或由调用方传入更稳妥<br>
List<EventListener<?>> listeners = listenerMap.get(eventType);<br>
if (listeners != null) {<br>
for (EventListener<?> l : listeners) {<br>
// 安全校验:确保监听器能处理该事件数据类型<br>
if (l instanceof EventListener) {<br>
((EventListener<T>) l).onEvent(event); // 强制转为具体泛型类型<br>
}<br>
}<br>
}<br>
}
⚠️ 注意:此处强制转换依赖调用方注册监听器时的类型一致性(例如注册 EventListener<user></user> 就只应接收 Event<user></user>),编译期已约束,运行时转换是安全的。
增强可用性:支持泛型通配与继承关系匹配(可选)
若需支持父类事件被子类监听器捕获(如监听 Event<object></object> 也能收到 Event<string></string>),可在查找逻辑中加入类型兼容判断:
- 遍历所有已注册的
Class>keys,用key.isAssignableFrom(eventType)找出兼容的监听器列表 - 按继承深度倒序匹配(优先精确匹配,再考虑父类),避免重复触发
- 此设计提升灵活性,但也增加查找开销,按需启用


















