咨询Java API中适配字符串监听-接收者关系的合适类
适合你场景的Java API监听类推荐
嘿,刚好你这个场景是典型的观察者/发布-订阅模式,Java API里已经有现成的实现可以直接用,不用自己从零写一套。下面给你梳理几个最适配的选项:
1. 传统观察者:java.util.Observable + java.util.Observer
这是JDK最早提供的观察者模式实现,虽然有点老,但胜在简单直接。不过要注意Observable是个类(不是接口),所以你的发射端对象需要继承它才能用。
适配你的StringReceiver
因为你的监听器是继承StringReceiver抽象类,所以需要写个适配器把它转换成Observer:
public class StringReceiverObserverAdapter implements Observer { private final StringReceiver receiver; public StringReceiverObserverAdapter(StringReceiver receiver) { this.receiver = receiver; } @Override public void update(Observable o, Object arg) { if (arg instanceof String) { receiver.receive((String) arg); } } }
发射端用法
让你的发射类继承Observable,发送字符串时调用:
public class StringEmitter extends Observable { public void sendString(String message) { setChanged(); // 标记状态变化 notifyObservers(message); // 通知所有观察者 } } // 使用示例 StringEmitter emitter = new StringEmitter(); emitter.addObserver(new StringReceiverObserverAdapter(myStringReceiver)); emitter.sendString("Hello from Observable!");
局限:因为Java是单继承,如果你的发射端已经继承了其他类,就没法用这个方案了。
2. 现代发布-订阅:Java 9+ Flow API
从Java 9开始,JDK引入了响应式流标准的实现,也就是java.util.concurrent.Flow包下的API,支持背压(控制消息流量),而且都是接口,灵活性更高。
核心组件
Flow.Publisher:负责发布消息(对应你的发射端)Flow.Subscriber:负责接收消息(对应你的监听器)- JDK还提供了现成的
SubmissionPublisher实现,直接用就行。
适配你的StringReceiver
写个适配器把StringReceiver转换成Flow.Subscriber<String>:
public class StringReceiverSubscriberAdapter implements Flow.Subscriber<String> { private final StringReceiver receiver; private Flow.Subscription subscription; public StringReceiverSubscriberAdapter(StringReceiver receiver) { this.receiver = receiver; } @Override public void onSubscribe(Flow.Subscription subscription) { this.subscription = subscription; // 请求接收所有消息,也可以按需调整数量 subscription.request(Long.MAX_VALUE); } @Override public void onNext(String item) { receiver.receive(item); } @Override public void onError(Throwable throwable) { // 这里可以添加错误处理逻辑,比如日志 throwable.printStackTrace(); } @Override public void onComplete() { // 消息发送完成时的处理,比如关闭资源 } }
发射端用法
直接用SubmissionPublisher:
// 创建发布者 SubmissionPublisher<String> publisher = new SubmissionPublisher<>(); // 订阅你的监听器 publisher.subscribe(new StringReceiverSubscriberAdapter(myStringReceiver)); // 发送字符串 publisher.submit("Hello from Flow API!"); // 记得关闭发布者(如果不再使用) publisher.close();
优势:接口设计,发射端无需继承任何类;支持背压,适合高并发场景;是现代Java的推荐方案。
3. JavaBean风格:java.beans.PropertyChangeSupport + PropertyChangeListener
如果你的场景是JavaBean环境(比如Swing、JavaFX或者企业级Bean),这个方案很合适,它原本是用来监听属性变化的,但也可以用来传递字符串消息。
适配你的StringReceiver
写个适配器:
public class StringReceiverPropertyAdapter implements PropertyChangeListener { private final StringReceiver receiver; public StringReceiverPropertyAdapter(StringReceiver receiver) { this.receiver = receiver; } @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getNewValue() instanceof String) { receiver.receive((String) evt.getNewValue()); } } }
发射端用法
用PropertyChangeSupport管理监听器:
public class StringBeanEmitter { private final PropertyChangeSupport support = new PropertyChangeSupport(this); public void addStringReceiver(StringReceiver receiver) { support.addPropertyChangeListener(new StringReceiverPropertyAdapter(receiver)); } public void sendString(String message) { // 第一个参数是事件名称,可以自定义,这里用"stringMessage" support.firePropertyChange("stringMessage", null, message); } } // 使用示例 StringBeanEmitter emitter = new StringBeanEmitter(); emitter.addStringReceiver(myStringReceiver); emitter.sendString("Hello from PropertyChange!");
优势:和JavaBean生态兼容,自带监听器管理逻辑,无需手动维护列表。
总结选择建议
- 如果是Java 9及以上项目,优先选Flow API,灵活且支持现代特性;
- 如果是老项目且发射端没有继承其他类,可以用
Observable/Observer; - 如果在JavaBean环境下,用
PropertyChangeSupport更贴合生态。
内容的提问来源于stack exchange,提问作者RealmSpy
相关产品推荐
相关产品推荐

