![](/img/trans.png)
[英]Cast Map<String, ? extends Object> to Map<String, Object>
[英]Can't pass a Map<Long, String> to a constructor with the argument Map<? extends Object, ? extends Object>. Why?
我有以下課程:
class MySelectBox {
public MySelectBox(Provider<Map<? extends Object, ? extends Object>> providerArrayIdToLabel) {
...
}
}
我試圖在使用此類的代碼中傳遞此信息:
new MySelectBox(new Provider<Map<Long, String>>{
... my implementation of Provider ...
});
編譯器給出以下錯誤:
The constructor MySelectBox(new Provider<Map<Long,String>>(){}) is undefined
為什么? 為什么方法未定義? 我應該在構造函數的簽名中更改什么才能使其接受Provider<Map<Long, String>>
注意:Provider接口是:
public interface Provider<T> extends javax.inject.Provider<T> {
T get();
}
將MySelectBox構造函數的聲明更改為:
public MySelectBox(Provider<? extends Map<? extends Long, ? extends String>> providerArrayIdToLabel)
要擴展答案,您的標題是錯誤的,並不反映問題。 您可以將Map<Long, String>
傳遞給Map<? extends Object, ? extends Object>
Map<? extends Object, ? extends Object>
Map<? extends Object, ? extends Object>
。 那不是問題。 如果X和Y不同,則不能將Provider<X>
傳遞給Provider<Y>
(此處X是Map<Long, String>
,Y是Map<? extends Object, ? extends Object>
)。 如果X是Y的子類型並不重要。這就像你不能將Provider<String>
傳遞給Provider<Object>
即使String是Object的子類型。 但是,如果您在頂級使用通配符,那么您將允許子類型 - 您可以將Provider<X>
傳遞給Provider<? extends Y>
Provider<? extends Y>
。
這就是Java泛型不變的效果。
由於該映射被傳遞給構造函數,我認為最好的解決方法是將鍵和值類型聲明為類泛型,因此每個實例都將包含特定鍵和值的映射:
class MySelectBox<K, V> {
public MySelectBox(Provider<Map<K, V>> map) {}
}
現在你可以安全地寫:
new MySelectBox<Long, String>(new Provider<Map<Long, String>>());
將您的代碼更改為
new MySelectBox(new Provider<Map<?, ?>>() {
@Override
public Map<Long, String> get() {
return null;
}
});
這是我嘗試解釋(這可能是錯誤的,因為我也很難用泛型):
編譯器不知道Provider只創建對象。 它認為Provider<Map<?, ?>>
是一個能夠保存Map<?, ?>
實例的對象(就像List<Map<?, ?>>
)。 由於Provider<Map<?, ?>>
應該能夠保存包含任何內容作為鍵的映射,以及任何作為值的Provider<Map<Long, String>>
,因此Provider<Map<Long, String>>
不是有效的類型替換。 實際上, Provider<Map<Long, String>>
只能包含Map<Long, String>
實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.