java泛型在消息订阅发布中将事件种类与载荷类型编译期绑定,通过标记接口ievent和泛型子类(如addconfigevent)实现类型安全;订阅时锁定具体泛型类型,发布时强类型构造,运行时按class分组分发,兼顾安全与灵活性。

Java 中泛型在通用消息订阅发布中规范事件数据类型,核心是让“事件种类”和“载荷类型”在编译期就绑定为一个不可分割的整体,而不是靠字符串、Object 或运行时判断来区分。
用空接口统一事件契约,泛型子类承载具体数据
所有事件实现同一个无方法的标记接口(如 IEvent),不定义业务字段;真正携带数据的是它的泛型实现类:
-
AddConfigEvent
:T 是配置的具体类型(如 WordPressConfig) -
SaveDocumentEvent
:T 是文档实体(如 MarkdownDoc) - 每个
AddConfigEvent<wordpressconfig></wordpressconfig>和AddConfigEvent<cnblogsconfig></cnblogsconfig>在 Java 类型系统里是两个完全不同的类,互不兼容
订阅时锁定泛型类型,避免转型与反射
订阅方法签名直接接收泛型事件类型,例如:
subscribe(Consumer<addconfigevent>> handler)</addconfigevent>- 注册时传入 lambda:
e -> sendNotification(e.getData().getSiteUrl()) - IDE 可自动补全
e.getData()的字段,编译器能校验是否调用了WordPressConfig特有方法 - 运行时无需
if (e instanceof ...)或Class.forName(...),也不依赖字符串匹配事件名
发布端强类型构造,数据原样传递
发布者创建事件对象时,必须明确指定泛型参数:
eventBus.publish(new AddConfigEvent<cnblogsconfig>() {{ setData(config); }});</cnblogsconfig>- 接收方拿到的就是
CnblogsConfig实例,不是Object,不需要强制转换 - 不同 T 的同一事件模板,在字节码层面就是不同类,天然隔离,不会误触发
内部存储按 Class> 分组,兼顾类型安全与运行时分发
事件总线底层可用 Map<class>, List<consumer>>></consumer></class> 管理监听器,但关键操作需配合类型擦除补偿:
- 注册时:用
handler.getClass().getGenericInterfaces()或传入Class<t></t>显式标记事件类型 - 发布时:
event.getClass()获取真实类型,查表后做一次(Consumer<t>) consumer</t>强转(仅此处,且安全) - 比全反射或字符串路由更轻量,比纯泛型单主题更灵活,适合中大型系统
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











