2 回答

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超9個(gè)贊
正如您在問題中途似乎意識(shí)到的那樣,您的問題不在于List<Ps>
與PsList
.
問題是你不能添加到Map<String, ? extends List<Ps>>
.
讓我們考慮一個(gè)更簡(jiǎn)單的例子:
void doSomething(Map<String, ? extends Number> map) { map.put(String, Integer.valueOf(0)); // Not allowed.}
問題在于,這Map<String, ? extends Number>
并不意味著“值可以是 Number 或 Number 的任何子類”。
每個(gè)通用類型對(duì)象都有一個(gè)特定的非通配符類型。意思是,不存在類型為 的 Map Map<String, ? extends Number>
。然而,以下情況可能存在:
Map<String, Integer>
(僅允許整數(shù)值)Map<String, Double>
(僅允許 Double 值)Map<String, Number>
(允許任何 Number 子類的值)
Map<String, ? extends Number>
指的是可能是上述任何一個(gè)的Map (或者,當(dāng)然,任何其他特定的 Number 子類)。編譯器不知道 Map 的值是什么特定類型,但 Map 的值仍然具有特定類型,但該類型不會(huì)以任何方式使用?
。
因此,再次查看示例方法:
void doSomething(Map<String, ? extends Number> map) {
// Not allowed. The caller might have passed a Map<String, Double>.
map.put(String, Integer.valueOf(0));
// Not allowed. The caller might have passed a Map<String, Integer>.
map.put(String, Double.valueOf(0));
// Not allowed. The caller might have passed a Map<String, Integer>
// or Map<String, Double>. This method has no way of knowing what the
// actual restriction is.
Number someNumber = generateNewNumber();
map.put(String, someNumber);
}
事實(shí)上,您無法向類型為上限通配符的 Map 或 Collection 添加任何內(nèi)容,因?yàn)闊o法知道這樣做是否正確且安全。
對(duì)于您的情況,最簡(jiǎn)單的解決方案是刪除通配符:
private void doSomething(Map<String, List<Ps>> map, boolean custom) {
// ...
map.put("stringValue", custom ? new PsList() : new ArrayList<Ps>());
}
如果您確實(shí)有具有不同值類型的映射,則需要告訴該方法正在使用的特定類型:
private <L extends List<Ps>> void doSomething(Map<String, L> map,
Supplier<L> listCreator) {
// ...
map.put("stringValue", listCreator.get());
}
然后你可以像這樣調(diào)用該方法:
if (custom) {
doSomething(psMap, PsList::new);
} else {
doSomething(listMap, ArrayList::new);
}

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
你絕對(duì)可以做到。這是一個(gè)例子:
public class MyClass {
static interface FooList<T> {}
static class Ps {}
static void doSomething(FooList<Ps> list) { }
static class PsList implements FooList<Ps> { }
public static void main(String[] args)
{
FooList psList = new PsList();
doSomething(psList);
System.out.println("HelloWorld!");
}
}
請(qǐng)參閱此處的演示。
添加回答
舉報(bào)