我讀到,自從Java 7以來,像在第一個語句中一樣在右側創建集合是錯誤的樣式,因爲編譯器可以從左側推斷出類型。爲什麼類型沒有被推斷,當離開泛型運算符
List<Integer> myList = new ArrayList<Integer>();
我的問題是初始化列表這樣的情況下,編譯器未找到的類型和我得到一個未經檢查的類型警告:
List<Integer> myList = new ArrayList();
我讀到,自從Java 7以來,像在第一個語句中一樣在右側創建集合是錯誤的樣式,因爲編譯器可以從左側推斷出類型。爲什麼類型沒有被推斷,當離開泛型運算符
List<Integer> myList = new ArrayList<Integer>();
我的問題是初始化列表這樣的情況下,編譯器未找到的類型和我得到一個未經檢查的類型警告:
List<Integer> myList = new ArrayList();
編譯器不推斷的類型,因爲你實例化一個原料ArrayList
。但它足夠聰明,可以警告您在使用此(原始)對象時可能會出現問題。
值得一提的是這個警告背後的原因。由於type erasure,關於List
的參數信息(<Integer>
)將在運行時完全消失,此時變量將保存類型爲Object
的元素。考慮這個片段:
List rawList = new ArrayList(); //raw list
rawList.add(new String("hello"));
rawList.add(new Double(12.3d));
List<Integer> intList = rawList; // warning!
這段代碼會編譯,但會產生很少的警告。有一個原始列表(rawList
),您可以添加任何非原始類型的列表,包括String
,Double
,等等。但是,當將此集合分配到列表中,該列表被指定爲只包含整數時,則這是問題。在運行時,當您試圖從intList
中獲取某個元素時,您會得到ClassCastException
,該元素應該是Integer
,但實際上是String
或其他東西。
長話短說 - 不要混合原始類型與泛型!
在你的情況下,編譯將可能人推斷的類型,如果你已經使用了鑽石:
List<Integer> list = new ArrayList<>(); //¯\_(ツ)_/¯
↑↑
因爲你已經忘記了尖括號(稱爲鑽石運營商)。
List<Integer> myList = new ArrayList<>();
這是語法上等同於
List<Integer> myList = new ArrayList<Integer>();
但不同於
List<Integer> myList = new ArrayList();
在你說的是,右側是一個原始類型含義ArrayList中可以容納每個對象的第3 (不僅是整數)。泛型只是編譯時間,並被編譯爲保存類型轉換。
您可以使用鑽石操作符推斷聲明類型爲JLS (§15.9)規定。
一個類的實例創建表達式指定一個類被實例化,接着可能類型參數(§4.5.1)或金剛石(「<>」)如果被實例化的類是通用的(§8.1.2 ),然後是構造函數的實際值參數列表(可能爲空)。
List<Integer> myList = new ArrayList<>();
注意採取通用 類實例化過程中利用自動類型推斷,你必須指定鑽石。
HashMap()
構造函數指的是HashMap
原始類型,而不是 的Map<String, List<String>>
類型。
爲什麼這給編譯器更多的信息比列表 myList = new ArrayList(),因爲在左邊的通用信息可用 –
PKuhn
因爲兩者在語義上是不同的。在鑽石中省略這種類型只是句法上的含義。 – lschuetze