Effective Java Item 23 note
Don’t use raw types in new code(又名heap pollution)
名稱定義:
Generic:一個class或interface宣告中有一個或多個type parameters就是個generic class或generic interface,ex:
List<E> : list of E
而generic class或generic interface,則稱generic types
每個generic types都定義一個raw type,即不帶任何實際類型參數的generic types
這個item重點就是在說,要注意你的generic class的使用方式,小心不要使用到raw type把generic types的safety跟expressiveness給抹消了。
例如用的人沒注意到形態上的不同,會出現runtime的ClassCastException。在java的哲學上,是希望error越早發現越好,最好是compile time發現error。
Ex:
Collection temp = new ArrayList<String>();
temp.add(123);for ( Iterator i = temp.iterator(); i.hasNext(); ) {
String s = (String)i.next(); // runtime exception
System.out.println(s);
}
======================================
Collection<String> temp = new ArrayList<String>();
//temp.add(123); // compile time exceptionfor ( Iterator i = temp.iterator(); i.hasNext(); ) {
String s = (String)i.next();
System.out.println(s);
}
底下是一些區分
List:raw type,沒有經過泛型的檢查。
List<Object>:可以在List中放入任何”物件”
List<String> temp = …;
List<Object> temp1 = …;
List t1 = temp; //是可以的
temp1 = temp; //是不行的,compile error
如果不確定元素的type的話,已經有提供Unbounded wildcard type來取代raw type的使用,例如:List<?>。但這樣就變成你沒辦法放任何除了null以外的東西進去。還有一個bounded wildcard type(item 28)
然後此item有兩個例外,都是因為generic type會在runtime被消除(item 25),List<String> s = new ArrayList<>(); 會被JVM看成List s = new ArrayList();:
- 在class literal使用的時候只能使用raw type,不能用generic type。
- if ( s instanceof ArrayList<String> ) 這樣是會compile error的,只能
if ( s instanceof ArrayList<?> ),然後<?>又太多餘,就變成這樣
if ( s instanceof ArrayList )