簡體   English   中英

Java通用列表<List <?擴展數>>

[英]Java Generic List<List<? extends Number>>

為什么java中我們做不到:

List<List<? extends Number>> aList = new ArrayList<List<Number>>();

即使這樣也可以:

List<? extends Number> aList = new ArrayList<Number>();

編譯器錯誤消息是:

Type mismatch: cannot convert from ArrayList<List<Number>> to List<List<? extends Number>>

在Java中,如果Car是派生類Vehicle ,那么我們可以將所有Cars視為Vehicles ; Car是一種Vehicle 但是, Cars List也不是Vehicles List 我們說List<Car>不是 List<Vehicle>

Java要求您明確告訴它何時使用協方差和逆向通配符,由?表示? 令牌。 看看你的問題發生在哪里:

List<List<? extends Number>> l = new ArrayList<List<Number>>();
//        ----------------                          ------
// 
// "? extends Number" matched by "Number". Success!

內部List<? extends Number> List<? extends Number> works,因為Number確實擴展了Number ,所以它匹配“ ? extends Number ”。 到現在為止還挺好。 下一步是什么?

List<List<? extends Number>> l = new ArrayList<List<Number>>();
//   ----------------------                    ------------
// 
// "List<? extends Number>" not matched by "List<Number>". These are
//   different types and covariance is not specified with a wildcard.
//   Failure.

但是,組合內部類型參數List<? extends Number> List<? extends Number>List<Number>不匹配; 類型必須完全相同 另一個通配符將告訴Java這個組​​合類型也應該是協變的:

List<? extends List<? extends Number>> l = new ArrayList<List<Number>>();

我對Java語法不是很熟悉,但似乎你的問題是:

協方差和反演

你一定要用? 在適當的時候鍵入通配符,不要將其作為一般規則來避免。 例如:

public void doThingWithList(List<List<? extends Number>> list);

允許您傳遞List<Integer>List<Long>

public void doThingWithList(List<List<Number>> list);

允許您只傳遞聲明為List<Number> 一個小的區別,是的,但使用通配符是強大而安全的 與它看起來相反, List<Integer>不是List<Number>的子類,也不是可分配的。 List<Integer>也不是List<? extends Number的子類List<? extends Number List<? extends Number ,這就是上面代碼無法編譯的原因。

你的語句沒有編譯,因為List<? extends Number> List<? extends Number>List<Number>類型不同。 前者是后者的超類型。

你試過這個嗎? 這里我表示List在其類型參數中是協變的,因此它將接受List<? extends Number>任何子類型List<? extends Number> List<? extends Number> (包括List<Number> )。

List<? extends List<? extends Number>> aList = new ArrayList<List<Number>>();

甚至這個。 這里右側的ArrayList的類型參數與左側的類型參數相同,因此方差不是問題。

List<List<? extends Number>> aList = new ArrayList<List<? extends Number>>();

你應該可以說

List<List<Number>> aList = new ArrayList<List<Number>>();

我傾向於避免? 盡可能輸入通配符。 我發現類型注釋中產生的費用不值得。

List<List<? extends Number>> aList = new ArrayList<List<? extends Number>>();
aList.add(new ArrayList<Integer>());

暫無
暫無

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

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