在使用Google Guava的优秀Multimap时,我遇到了一些与泛型有关的问题。我定义了一个类型处理程序Handler如下:
public interface Handler<T extends Serializable> {
void handle(T t);
}
在另一个类中,我定义了一个multimap,将一个字符串映射到一组处理程序。
private Multimap<String, Handler<? extends Serializable>> multimap =
ArrayListMultimap.create();
现在当我尝试使用multimap来做一些事情时,我遇到了编译器错误。我的第一次尝试看起来像这样:
public <T extends Serializable> void doStuff1(String s, T t) {
Collection<Handler<T>> collection = multimap.get(s);
for (Handler<T> handler : collection) {
handler.handle(t);
}
}
这导致了以下错误:
类型不匹配:无法将 Collection<Handler<? extends Serializable>>
转换为 Collection<Handler<T>>
之后,我尝试按照以下方式编写代码:
public void doStuff2(String s, Serializable serializable) {
Collection<Handler<? extends Serializable>> collection = multimap.get(s);
for (Handler<? extends Serializable> handler : collection) {
handler.handle(serializable);
}
}
很不幸,这也失败了:
类型Handler<capture#1-of ? extends Serializable>中的方法handle(capture#1-of ? extends Serializable)对于参数(Serializable)不适用
非常感谢任何帮助。谢谢。
更新:
我唯一成功解决此问题的方法是抑制编译器警告。给定以下处理程序:
public interface Handler<T extends Event> {
void handle(T t);
Class<T> getType();
}
我可以将事件总线编写为如下形式。
public class EventBus {
private Multimap<Class<?>, Handler<?>> multimap = ArrayListMultimap.create();
public <T extends Event> void subscribe(Handler<T> handler) {
multimap.put(handler.getType(), handler);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void publish(Event event) {
Collection<Handler<?>> collection = multimap.get(event.getClass());
for (Handler handler : collection) {
handler.handle(event);
}
}
}
我猜没有更少甚至不需要使用@SuppressWarnings来处理这个问题了?