[英]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.