可实现零包装、无反射、纯接口调用的消息广播器。利用Java泛型擦除特性,统一用Object承载所有消息类型,通过原始接口Broadcaster和ArrayList实现轻量注册与单层分发。

直接利用类型擦除后所有泛型实例共享同一字节码类的特性,可以绕过泛型类型分发开销,实现零包装、无反射、纯接口调用的消息广播器。
核心思路:用原始类型承载多态行为
Java中 List 和 List 编译后都是 List 类型,字段和方法签名统一为 Object。这意味着——只要不依赖运行时泛型类型信息,就能用一个底层类服务所有消息类型,避免为每种 T 生成独立广播器实例或做类型桥接。
- 定义广播器核心为原始接口:
interface Broadcaster { void broadcast(Object msg); } - 所有具体消息类型(
EventA、LogEntry、Signal)都直接传入Object,不封装、不转换 - 订阅者也只声明接收
Object,由业务方自行强转(或配合Class运行时校验)
轻量注册与分发:跳过泛型路由层
传统泛型广播器常为每种类型维护独立 Map,带来哈希查找+泛型擦除桥接+多次装箱。而利用擦除红利,可退化为单层结构:
- 用
ArrayList存所有监听器,统一调用> accept(msg) - 注册时不传泛型类型参数,只注册裸
Consumer实例(如System.out::println可直接注册) - 广播时无类型判断、无
instanceof分支、无泛型参数匹配逻辑——就是一次for循环调用
规避擦除限制的实用技巧
类型擦除导致无法 new T[] 或 msg instanceof T,但高频广播场景中这些本就应被规避:
- 不用泛型数组:内部存储用
Object[]或ArrayList,避免new T[16]触发ClassCastException - 不依赖
instanceof过滤:若需按类型分发,改用消息自带type()方法或short typeId字段,比反射获取泛型更高效 - 避免桥接方法开销:不写
这类泛型方法,直接暴露void register(Consumer c) register(Consumer
一个极简可运行骨架
不引入任何第三方依赖,无泛型类、无反射、无包装对象:
public final class LightBroadcaster {
private final List<consumer>> listeners = new ArrayList();
public void register(Consumer<object> l) { listeners.add(l); }
public void broadcast(Object msg) { listeners.forEach(l -> l.accept(msg)); }
public void clear() { listeners.clear(); }
}</object></consumer>
使用时:broadcaster.broadcast(new UserLoginEvent("u123")); —— 消息对象本身是普通 POJO,不继承基类、不实现标记接口,完全零侵入。










