generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods.
泛型能在定義類,接口和方法時將類型(類和接口)作為參數。和方法聲明時的形式參數很類似,都是為了在不同的輸入時重用相同的代碼。不同的是形式參數輸入的是值而泛型是類型。
1.編譯時更加強的(Stronger)類型檢測
java編譯器對泛型代碼進行強類型檢測,一旦檢測到代碼違反類型安全就發出類型錯誤。
修復編譯錯誤要比運行錯誤容易,因為運行錯誤很難找到問題所在。
2.不用類型轉換
//沒有使用泛型
List list = new ArrayList();
list.add("without generics");
//需要強制類型轉換
String s1 = (String) list.get(0);
//使用泛型
List<String> list2 = new ArrayList<String>();
list2.add("generics");
String s2 = list2.get(0);//不需要轉換
3.使程序員能實現適用更加普遍的算法
通過使用泛型,使程序員能實現普遍的算法,算法將是能使用於不同類型的,能自定義的,類型安全的,易讀的。
如只寫一個排序方法,就能夠對整形數組、字符串數組甚至支持排序的任何類型的數組進行排序。
A generic type is a generic class or interface that is parameterized over types.
泛型是一種通用的類或接口,通過類型參數化的。
泛型類以下面的格式定義:
class name<T1, T2, ..., Tn> { /* ... */ }
通過Box類的非泛型版和泛型版來學習一下:
非泛型:
//non-generic class
public class Box {
private Object object;
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
泛型:
//generic class
public class Box<T> {
//T表示Type
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
類型參數命名規范按約定的習俗,類型參數的名字都是由一個大寫字母構成。
E - Element 元素(used extensively by the Java Collections Framework)
K - Key 鍵
N - Number 數值
T - Type 類型
V - Value 值
S,U,V etc. - 2nd, 3rd, 4th types 第二種,第三種,第四種類型
為了獲得泛型類的引用,必須執行泛型類的調用,使用具體的值來代替T,如Integer。
//獲得引用
Box<Integer> integerBox;
//實例化
integerBox = new Box<Integer>();
泛型類的調用類似於普通的方法調用,只是泛型類傳遞的是類型參數(type argument)而方法調用傳遞的是參數(argument)。
泛型類可能有多種類型的參數。如下所示:
public interface Pair<K,V>{
public K getKey();
public V getValue();
}
public class OrderedPair<K,V> implements Pair<K,V>{
private K key;
private V value;
public OrderedPair(K key,V value){
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
}
//實例化
Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);
Pair<String, String> p2 = new OrderedPair<String, String>("hello", "world");
//Java SE7開始出現的新語法
OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);
OrderedPair<String, String> p2 = new OrderedPair<>("hello", "world");
//參數化的類型
OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));