2012-08-31 66 views
3

關於Java中泛型的另一個非常基本的問題,直接來自previous question of mine。我們不是通過編寫下面的代碼兩次向編譯器提供相同的信息。爲什麼我們需要在左側和右側都提供這兩者?爲什麼我們需要提供兩次通用信息?

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

編輯:當我在它,它不需要任何更多的Java 7中起了一些答案看看。但我想知道java 7之前不可能的原因是什麼?

回答

3

因爲pre java 7不支持構造函數的泛型類型推斷。這在鑽石運營商的java 7中得到了解決。
你也可以寫通用的工廠方法作爲一種解決方法,如:

public static <T> List<T> createArrayList() { 
     return new ArrayList<T>(); 
} 

然後

List<Integer> list = createArrayList(); 

這是值得商榷的,但工程。也許爲地圖和其他多重論證的泛型類型帶來好處。


到編輯:也許是語言的設計者決定不支持泛型類型推斷,因爲他們實現與類型擦除泛型。另一個可疑的決定,我認爲...否則,不要認爲在早期的Java版本中有任何反對這個特性的嚴重原因。 (並且通過Peter Lawrey的附錄,它仍然不存在。)

+1

從技術上講''''不會進行類型推斷,它只是不檢查如果你編寫'List numbers = new ArrayList <>();'它確定但是'列表 numbers = new ArrayList <>(){};'不是因爲它需要知道創建類的實際類型。 –

+0

@PeterLawrey:謝謝你的補充。 – zeller

4

正在引入鑽石操作員來移除這些冗餘信息。

看到這個鏈接SO以及What is the point of the diamond operator in Java 7?

從我讀/理解我不認爲泛型是做到了在Java中。這個?最後介紹的操作員是一件很痛苦的工作。有刪除的事實表明,在我看來,它是鞋子。它可以完成這項工作,但我認爲它可能會更好

+0

請參閱編輯。我想了解java 7之前的問題是什麼,這迫使設計人員以這種方式進行設計。 – Geek

1

因爲一個是參考,一個是實現。該行的左側設置了存儲實例化變量的引用。由於Java使用「運行時類型擦除」來實現泛型,因此除了引用賦值之外的任何代碼都無法知道Generic參數是什麼分配。

編輯 - 我不知道J7的變化(我有點過時:)) - 看起來他們解決了這個問題。

0

除了其他答案中所述的原因外,本示例中右側的參數不需要與左側的參數完全相同。例如:

List<? extends Calendar> cals = new ArrayList<GregorianCalendar>();