我希望避免代码中的显式强制转换,这是我到目前为止所做的,但是编译器给了我一些错误,我不知道如何在没有强制转换的情况下修复它。
我有一个带有监听器映射的类,以及一些通知侦听器的方法:
public class MessageDispatcher {
private final Map<String, List<ControllerMessageWatcher<? extends ControllerMessage>>> watchers;
public void registerMessageWatcher(Class<? extends ControllerMessage> classToWatch, final ControllerMessageWatcher<?> controllerMessageWatcher) {
this.watchers.computeIfAbsent(classToWatch.getSimpleName(), k -> new ArrayList<>()).add(controllerMessageWatcher);
}
public synchronized void receive(StatusMessage statusMessage) {
List<ControllerMessageWatcher<?>> watchers = this.watchers.get(statusMessage.getClass().getSimpleName());
if (watchers != null)
watchers.forEach(controllerMessageWatcher -> controllerMessageWatcher.newMessage(statusMessage));
// Required type: capture of ? Provided: StatusMessage <-- error here! ^^^^
}
public synchronized void receive(UpdateDBMessage updateDBMessage) {
List<ControllerMessageWatcher<?>> watchers = this.watchers.get(updateDBMessage.getClass().getSimpleName());
if (watchers != null)
watchers.forEach(controllerMessageWatcher -> controllerMessageWatcher.newMessage(updateDBMessage));
// Required type: capture of ? Provided: UpdateDBMessage <-- error here! ^^^^
}
}这是侦听器的接口:
public interface ControllerMessageWatcher<T extends ControllerMessage> {
void newMessage(T message);
}这就是我希望使用的监听器的实现,避免抛出:
public class Status implements ControllerMessageWatcher<StatusMessage> {
@Override
public void newMessage(StatusMessage message) {
...
}
}所有工作,但接收的方法,这会产生错误(或未经检查的警告,如果我删除通配符)。
我想要实现的是避免在每个newMessage方法中进行显式强制转换(如果删除所有泛型部分,我就必须这样做)。
在从newMessage方法调用MessageDispatcher.receive()时避免错误/警告(现在有)(请参阅该方法中的注释)
这是ControllerMessage,StatusMessage和UpdateDBMessage
public abstract class ControllerMessage {
private String messageId;
// ... getter setter
}public class StatusMessage extends ControllerMessage{
private String aField;
// ... getter setter
}public class UpdateDBMessage extends ControllerMessage{
private String aField;
// ... getter setter
}发布于 2020-07-28 10:13:19
我认为你的设计是从根本上破坏的,因为你使用了反思。
public void registerMessageWatcher(
Class<? extends ControllerMessage> classToWatch,
final ControllerMessageWatcher<?> controllerMessageWatcher
)在API级别上,这一步使编译器无法管理继承。
一个小的改进将是使类型一致。
public <T extends ControllerMessage> void registerMessageWatcher(
Class<T> classToWatch,
final ControllerMessageWatcher<T> controllerMessageWatcher
)现在,我们正在跟踪我们的类类型,无论是好是坏,但我们仍然需要种姓,以保持在地图上的类。
private final Map<Class<?>, List<ControllerMessageWatcher<?>>> watchers;
List<ControllerMessageWatcher<T>> getWatchers( Class<T> clazz ){
return (List<ControllerMessageWatcher<T>>)watchers.get(clazz);
}为了避免铸造,我会
public interface ControllerMessageWatcher<T extends ControllerMessage> {
void newMessage(ControllerMessage message);
}我不知道你和你的观察者在做什么,这会有新的信息来区分类型。这样你就可以拥有。
List<ControllerMessageWatcher<? extends ControllerMessage>> watchers;
watchers.forEach( w -> w.newMessage( message ) );然后用接口替换抽象类。
interface ControllerMessage{
String getMessageId();
String getAField();
}现在由特定的观察人员来获取相关信息。还可以为不相关的字段创建默认方法。
https://stackoverflow.com/questions/63128708
复制相似问题