4 回答

TA貢獻1772條經驗 獲得超6個贊
這個問題
List<String> list = new LinkedList();
在左側,您使用的是泛型類型List<String>
,在右側,您使用的是原始類型LinkedList
。Java中的原始類型實際上僅存在與前泛型代碼的兼容性,并且除非絕對必須,否則不應在新代碼中使用。
現在,如果Java從一開始就具有泛型并且沒有類型,例如LinkedList
,最初在它具有泛型之前創建的類型,它可能已經使得它使得泛型類型的構造函數自動從左側推斷其類型參數 - 如果可能的話,指派的一面。但事實并非如此,它必須以不同的方式處理原始類型和泛型類型以實現向后兼容性。這使得他們需要制作一種稍微不同但同樣方便的方式來聲明一個通用對象的新實例,而不必重復其類型參數......菱形運算符。
就您的原始示例而言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
s 的無參數構造函數!

TA貢獻2065條經驗 獲得超14個贊
你的理解有點缺陷。鉆石操作員是一個很好的功能,因為你不必重復自己。在聲明類型時定義類型一次是有意義的,但在右側再次定義它是沒有意義的。DRY原則。
現在解釋有關定義類型的所有模糊。你是正確的,在運行時刪除了類型,但是一旦你想要從具有類型定義的List中檢索某些內容,你就會將它作為你在聲明列表時定義的類型返回,否則它會丟失所有特定的功能并且只有對象功能,除非您將檢索到的對象強制轉換為原始類型,這有時會非常棘手并導致ClassCastException。
使用List<String> list = new LinkedList()
將獲得rawtype警告。
添加回答
舉報