Java泛型通配符问题

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来处理这个问题?

Vin*_*tin 2

如果您定义以下内容,效果会更好:

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”,如果您认为我是正确的,请投票给我的答案。