簡體   English   中英

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

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

考慮以下代碼:

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

為什么以下服務實現無法編譯?

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

因為<? extends BaseType> <? extends BaseType>是指“未指定的某些子類型鹼基類型”,和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;
    }
}

ServiceImpl不能是接口,因為您的實現不能在接口中。 將其更改為基類並嘗試。

你寫什么

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

Java對extents一無所知

至少使用extends

Service#get()方法的返回類型指定為

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

而您正在嘗試返回一個

Map<AImpl, List<BImpl>> 

您可以使用協變返回類型。 似乎您認為這里就是這種情況。 但是問題在於這種協方差不適用於通用類型參數。 盡管List<BImpl>List<? extends B>的子類型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>>

結構上類似但更簡單的情況是List<Integer>不是List<Number>的子類型。

您可以在“ Service界面中將返回類型更改為

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

使它工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM