Tom*_*Tom 14 java generics guava
在使用Google Guava优秀的Multimap时,我遇到了Generics的一些问题.我有一个类型Handler定义为这样
public interface Handler<T extends Serializable> {
void handle(T t);
}
Run Code Online (Sandbox Code Playgroud)
在另一个类中,我定义了一个将String映射到Handlers集合的多图.
private Multimap<String, Handler<? extends Serializable>> multimap =
ArrayListMultimap.create();
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
这导致以下错误.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是也失败了:
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();
}
Run Code Online (Sandbox Code Playgroud)
我可以这样写事件总线.
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想没有办法用更少甚至没有@SuppressWarnings来处理这个问题?
如果您定义以下内容,效果会更好:
private Multimap<String, Handler<Serializable>> multimap =
ArrayListMultimap.create();
Run Code Online (Sandbox Code Playgroud)
更新:对您的问题的解释。
当你有类似的东西..
private Multimap<String, Handler<? extends Serializable>> multimap;
Run Code Online (Sandbox Code Playgroud)
这意味着 multimap 可以接受 ANY Handler<N>
where N Extends Serializable
。我们假设它将包含一个 type 的值Handler<Foo>
和一个 type 的值Handler<Bar>
。Foo
且不Bar
相关且不相互延伸。
当在你的函数中你想要使用一个类型来表示 的所有可能值的类型时Handler<? extends Serializable>
,你试图表达一个同时是Foo
和 的类型Bar
,但是不存在这样的类型。
这解释了你的编译器问题。现在删除这个“-1”,如果您认为我是正确的,请投票给我的答案。