带通配符的泛型(Map <! - ?extends A,List <?extends B - >&gt;)

时间:2014-04-08 08:41:49

标签: java list generics map

请考虑以下代码:

public interface A {};

public class AImpl implements A {};

public interface B {};

public class BImpl implements B {};

public interface Service{
  Map<? extends A, List<? extends B>> get();
}

为什么以下的Service实现不能编译?

public class ServiceImpl implements Service {
  public Map<AImpl, List<BImpl>> get() {
    return null;
  }
}

编译错误:

  

返回类型与Service.get()

不兼容

但是下面的代码编译:

public interface Service{
   List<? extents B> get();
}

public class ServiceImpl implements Service{
   public List<BImpl> get(){
       return null;
   }
}

4 个答案:

答案 0 :(得分:3)

因为<? extends BaseType>表示&#34;某些未指定的子类型BaseType&#34;和class Sub extends BaseType,而BaseType的子类型不是它。请阅读Java Generics FAQ,特别是从Wildcard Capture部分开始,了解更多详情。

您应该正确地验证您的代码:

public interface Service<K extends A, V extends B> {
    Map<K, List<V>> get();
}

public class ServiceImpl implements Service<AImpl, BImpl> {
    @Override
    public Map<AImpl, List<BImpl>> get() {
        return null;
    }
}

答案 1 :(得分:0)

ServiceImpl不能是接口,因为您的实现不能在接口中;将其更改为基础基类并尝试。

答案 2 :(得分:0)

你写的是什么?

Map<? extents A, List<? extents B> get();

java对extents

一无所知

至少使用extends

答案 3 :(得分:0)

Service#get()方法的返回类型指定为

Map<? extends A, List<? extends B>> get();

你正试图返回

Map<AImpl, List<BImpl>> 

您可以使用协变返回类型。似乎你认为这就是这种情况。但问题是这种协方差不适用于泛型类型参数。虽然List<BImpl>List<? extends B>的子类型,但这并不意味着Map<AImpl, List<BImpl>>Map<? extends A, List<? extends B>>的子类型。

结构相似但更简单的情况是List<Integer>不是List<Number>的子类型。

您可以将Service界面中的返回类型更改为

Map<? extends A, ? extends List<? extends B>> get();

让它发挥作用。