【发布时间】:2011-05-14 06:02:28
【问题描述】:
在使用 Google Guava 出色的 Multimap 时,我遇到了一些泛型问题。我有一个这样定义的类型处理程序
public interface Handler<T extends Serializable> {
void handle(T t);
}
在另一个类中,我定义了一个将字符串映射到处理程序集合的多映射。
private Multimap<String, Handler<? extends Serializable>> multimap =
ArrayListMultimap.create();
现在,当我尝试使用多图进行操作时,我遇到了编译器错误。我的第一次尝试是这样的:
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);
}
}
导致以下错误。
Type mismatch: cannot convert from Collection<Handler<? extends Serializable>>
to 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);
}
}
不幸的是也失败了:
The method handle(capture#1-of ? extends Serializable) in the type
Handler<capture#1-of ? extends Serializable> is not applicable for the arguments
(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 来处理这个问题?
【问题讨论】:
-
我试图简化我的问题,但我刚刚意识到我完全掩盖了多图的意图。我的处理程序的类型参数实际上并不是从 Serializable 扩展而来,而是从 Event 接口扩展而来,并且 multimap 的键实际上不是 String,而是 Class
,即。 e.事件类型与可以处理该特定事件的处理程序之间存在相关性。 (每种事件类型可能有多个处理程序)。包含多图的类是事件总线。事件处理程序可以订阅总线并在某个事件发生时得到通知。 -
如果您仍然没有为您找到解决方案,那么我建议您编辑您的问题,以便人们可以帮助您。
-
谢谢,文森特。我就是这么做的。