Java泛型通配符问题 [英] Java Generics Wildcards Question

查看:175
本文介绍了Java泛型通配符问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Google Guava优秀的Multimap时,我遇到了泛型的一些问题。我有一个类型的Handler定义为这样的

  public interface Handler< T extends Serializable> {
void handle(T t);





$ b

在另一个类中,我定义了一个将String映射到集合的multimap

  private Multimap< String,Handler<扩展Serializable>> multimap = 
ArrayListMultimap.create();

现在,当我尝试使用multimap进行操作时,出现编译器错误。我的第一次尝试看起来像这样:

  public< T extends Serializable> void doStuff1(String s,T t){
Collection< Handler< T>> collection = multimap.get(s); (Handler< T>处理程序:集合){
handler.handle(t);
}
}

导致以下错误。



类型不匹配:无法从Collection< Handler转换<?扩展Serializable>>
到Collection< Handler< T>>



之后,我试着像这样编码


$ b

  public void doStuff2(String s,Serializable serializable){
Collection< Handler<扩展Serializable>> collection = multimap.get(s); (Handler< ;? extends Serializable> handler:collection)
{
handler.handle(serializable);
}
}

不幸失败:



类型
Handler<捕获#1中的方法句柄(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扩展事件> void subscribe(Handler< T> handler){
multimap.put(handler.getType(),handler);

$ b $ @SuppressWarnings({rawtypes,unchecked})
public void publish(Event event){
Collection< Handler<>> ; collection = multimap.get(event.getClass());
for(Handler handler:collection){
handler.handle(event);
}
}
}

我想没有办法处理这个更少或甚至没有@SuppressWarnings?

解决方案

如果您定义了以下内容,它将会更好:

  private Multimap< String,Handler< Serializable>> multimap = 
ArrayListMultimap.create();

更新:解释您的问题。



当你有类似的东西时。

  private Multimap< String,Handler<扩展Serializable>>多重映射; 

这意味着multimap可以接受任何 Handler< N> 其中 N扩展可序列化。让我们考虑它将包含类型 Handler< Foo> 的值和类型 Handler< Bar> 的值。 Foo Bar 是不相关的,并且不会相互延伸。



在你的函数中,你想用一个类型来表示 Handler的所有可能值的类型。扩展Serializable> ,你试图表达一个类型,它同时是 Foo Bar ,但没有这种类型。



这解释了编译器的问题。现在删除这个-1,如果你认为我是正确的,就投我的答案。


I'm facing some problems with Generics when using Google Guava's excellent Multimap. I have a type Handler defined as such

public interface Handler<T extends Serializable> {
    void handle(T t);
} 

In another class I've defined a multimap that maps a String to a collection of Handlers.

private Multimap<String, Handler<? extends Serializable>> multimap = 
    ArrayListMultimap.create();

Now when I try to do stuff with the multimap, I'm getting compiler errors. My first attempt looked like this:

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);
    }
}

which resulted in the following error.

Type mismatch: cannot convert from Collection<Handler<? extends Serializable>> to Collection<Handler<T>>

Afterwards, I tried to code it like this

public void doStuff2(String s, Serializable serializable)  {
    Collection<Handler<? extends Serializable>> collection = multimap.get(s);
    for (Handler<? extends Serializable> handler : collection) {
        handler.handle(serializable); 
    }
}

which unfortunately failed as well:

The method handle(capture#1-of ? extends Serializable) in the type Handler<capture#1-of ? extends Serializable> is not applicable for the arguments (Serializable)

Any help would be greatly appreciated. Thanks.

Update:

The only way I have managed to fix this is by suppressing compiler warnings. Given the following handler:

public interface Handler<T extends Event> {
    void handle(T t);

    Class<T> getType();
}

I can write the event bus as such.

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);
        }
    }
}

I guess there's no way to handle this with less or even without @SuppressWarnings?

解决方案

It will work better if you define:

private Multimap<String, Handler<Serializable>> multimap = 
    ArrayListMultimap.create();

Update: Explaination of your problem.

When you have something like ..

private Multimap<String, Handler<? extends Serializable>> multimap;

It means that multimap can accept ANY Handler<N> where N Extends Serializable. Let's consider that it will contain a value of type Handler<Foo> and a value of type Handler<Bar>. Foo and Bar are unrelated and do not extend from each other.

When in your function you want to use a type to represent the type of all the possible values of Handler<? extends Serializable>, you are trying to express a type which is at the same time Foo and Bar, but there is no such a type.

This explains your problem with the compiler. Now remove this "-1" and vote for my answer if you think I am correct.

这篇关于Java泛型通配符问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆