Java 7中的菱形運算符(<>)有什麼意義?

Java 7中的菱形運算符容許以下代碼: 安全

List<String> list = new LinkedList<>();

可是,在Java 5/6中,我能夠簡單地編寫: ide

List<String> list = new LinkedList();

我對類型擦除的理解是這些徹底相同。 (不管如何,泛型都會在運行時刪除)。 函數

爲何要打擾鑽石呢? 它容許哪些新功能/類型安全? 若是它沒有產生任何新功能,爲何他們將其稱爲功能? 我對這個概念的理解有缺陷嗎? spa


#1樓

此行致使[unchecked]警告: code

List<String> list = new LinkedList();

所以,問題發生了變化:爲何僅在建立新集合時才自動取消[unchecked]警告? 對象

我認爲,而後添加<>功能會更加困難。 開發

UPD :我還認爲,若是合法地使用原始類型「僅用於幾件事」會形成混亂。 編譯器


#2樓

您的理解有些瑕疵。 Diamond運算符是一個不錯的功能,由於您沒必要重複本身的操做。 在聲明類型時一次定義類型是有意義的,可是在右側再次定義它是沒有意義的。 DRY原理。 string

如今來解釋有關定義類型的全部模糊性。 您是對的,該類型在運行時已刪除,可是一旦您想從具備類型定義的列表中檢索某些內容,就能夠在聲明該列表時將其恢復爲您定義的類型,不然它將丟失全部特定功能而且僅具備對象功能,除非您將檢索到的對象轉換爲原始類型,不然有時會很是棘手,並致使ClassCastException。 io

使用List<String> list = new LinkedList()將得到原始類型警告。


#3樓

當您寫List<String> list = new LinkedList(); ,編譯器會產生「未經檢查」的警告。 您可能會忽略它,可是若是您過去曾經忽略這些警告,則可能還會錯過一條警告消息,該警告通知您有關實型安全問題。

所以,最好編寫一個不會生成額外警告的代碼,而且菱形運算符容許您以便捷的方式進行操做,而無需沒必要要的重複。


#4樓

Diamond運算符的目的只是在聲明泛型類型時減小代碼的類型。 它對運行時沒有任何影響。

若是您在Java 5和6中指定,則惟一的區別是

List<String> list = new ArrayList();

是您必須在list指定@SuppressWarnings("unchecked") (不然,您將得到未選中的強制轉換警告)。 個人理解是,鑽石運營商正在努力使開發變得更容易。 與泛型的運行時執行徹底無關。


#5樓

與問題

List<String> list = new LinkedList();

是在左側,您使用的是通用類型List<String> ,而在右側,您使用的是原始類型LinkedList 。 Java中的原始類型實際上僅存在於與前泛型代碼的兼容性,而且除非絕對必要,不然絕對不能在新代碼中使用。

如今,若是Java從一開始就具備泛型,而且沒有諸如LinkedList類的類型,而該類型最初是在具備泛型以前建立的,則它可能已經作到了,這樣泛型類型的構造函數會自動從Java推斷其類型參數。若是可能的話,在做業的左側。 但事實並不是如此,爲了向後兼容,必須對原始類型和泛型類型進行不一樣的處理。 這使得他們須要採起一種稍微不一樣但一樣方便的方式來聲明泛型對象的新實例,而沒必要重複其類型參數……菱形運算符。

就您的List<String> list = new LinkedList()的原始示例而言,編譯器會爲該分配生成警告,由於它必須這樣作。 考慮一下:

List<String> strings = ... // some list that contains some strings

// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);

存在泛型以提供編譯時保護以防止作錯事。 在上面的示例中,使用原始類型意味着您沒有得到此保護,而且在運行時會收到錯誤消息。 這就是爲何您不該該使用原始類型的緣由。

// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);

可是,菱形運算符容許將賦值的右側定義爲具備與左側相同類型參數的真實泛型實例,而沒必要再次鍵入這些參數。 它使您能夠與使用原始類型幾乎相同的工做來保持泛型的安全。

我認爲關鍵要理解的是原始類型(不帶<> )不能與泛型類型相同。 聲明原始類型時,不會得到任何好處和泛型的類型檢查。 您還必須記住, 泛型是Java語言的通用組成部分 ……它們不只僅適用於Collection的no-arg構造函數!

相關文章
相關標籤/搜索