简体   繁体   English

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

[英]Generics with Wildcards (Map<? extends A, List<? extends B>>)

Consider the following code: 考虑以下代码:

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

Why does the following implementation of Service not compile? 为什么以下服务实现无法编译?

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

Compiler error: 编译器错误:

The return type is incompatible with Service.get() 返回类型与Service.get()不兼容

But the following code compile: 但是下面的代码会编译:

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

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

Because <? extends BaseType> 因为<? extends BaseType> <? extends BaseType> means "some unspecified sub-type BaseType", and class Sub extends BaseType , while sub-type of BaseType , is not it. <? extends BaseType>是指“未指定的某些子类型碱基类型”,和class Sub extends BaseType ,而子类型的BaseType ,是不是。 Read Java Generics FAQ , in particular starting from Wildcard Capture section, for more details. 阅读Java Generics FAQ ,特别是从Wildcard Capture部分开始,以获取更多详细信息。

You should generify your code properly: 您应该适当地泛化代码:

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

ServiceImpl cannot be an interface because your Implementation cannot be in an interface; ServiceImpl不能是接口,因为您的实现不能在接口中。 Change it to a base base class and try it. 将其更改为基类并尝试。

What do you write? 你写什么

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

java doesn't know anything about extents Java对extents一无所知

At least use extends 至少使用extends

The return type of the Service#get() method is specified as Service#get()方法的返回类型指定为

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

And you are trying to return a 而您正在尝试返回一个

Map<AImpl, List<BImpl>> 

You can use covariant return types. 您可以使用协变返回类型。 And it seems like you thought this would be the case here. 似乎您认为这里就是这种情况。 But the problem is that this covariance does not apply to the generic type parameters. 但是问题在于这种协方差不适用于通用类型参数。 Although List<BImpl> is a subtype of List<? extends B> 尽管List<BImpl>List<? extends B>的子类型List<? extends B> List<? extends B> , this does not mean that Map<AImpl, List<BImpl>> is a subtype of Map<? extends A, List<? extends B>> List<? extends B> ,这并不意味着Map<AImpl, List<BImpl>>Map<? extends A, List<? extends B>>的子类型Map<? extends A, List<? extends B>> Map<? extends A, List<? extends B>> Map<? extends A, List<? extends B>> . Map<? extends A, List<? extends B>>

A structurally similar but simpler case is that List<Integer> is not a subtype of List<Number> . 结构上类似但更简单的情况是List<Integer>不是List<Number>的子类型。

You could change the return type in the Service interface to 您可以在“ Service界面中将返回类型更改为

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

to make it work. 使它工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM