泛型
泛型類的定義
語法
class 泛型類名稱<類型形參列表> {
// 這裏可以使用類型參數
}
class ClassName<T1, T2, ..., Tn> {
}
class 泛型類名稱<類型形參列表> extends 繼承類/* 這裏可以使用類型參數 */ {
// 這裏可以使用類型參數
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分類型參數
}
類型形參一般使用一個大寫字母表示,常用的名稱有:
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
T 表示 Type
定義一個泛型類順序表
public class MyArrayList<E> {
private E[] array;
private int size;
public MyArrayList() {
// 泛型類型無法直接創建數組,具體的見下面的注意事項
array = (E[])new Object[16];
size = 0;
}
// 尾插
public void add(E e) {
array[size++] = e;
}
// 尾刪
public E remove() {
E element = array[size - 1];
array[size - 1] = null; // 將容器置空,保證對象被正確釋放
size--;
return element;
}
}
定義一個泛型類鏈表
public class MyLinkedList<E> {
public static class Node<E> {
private E value;
private Node<E> next;
private Node(E e) {
value = e;
next = null;
}
}
private Node<E> head;
private int size;
public MyLinkedList() {
head = null;
size = 0;
}
// 頭插
public void pushFront(E e) {
Node<E> node = new Node<>(e);
node.next = head;
head = node;
size++;
}
// 尾插
public void pushBack(E e) {
if (size == 0) {
pushFront(e);
return;
}
Node<E> cur = head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = new Node<E>(e);
size++;
}
}
泛型類的使用
語法
泛型類<類型實參> 變量名; // 定義一個泛型類引用
new 泛型類<類型實參>(構造方法實參); // 實例化一個泛型類對象
MyArrayList list = new MyArrayList();
類型擦除
class MyArrayList<E> {
// E 會被擦除爲 Object
}
class MyArrayList<E extends Comparable<E>> {
// E 被擦除爲 Comprable
}
類型擦除主要看其類型邊界而定
編譯器在類型擦除階段在做什麼?
- 將類型變量用擦除後的類型替換,即 Object 或者 Comparable
- 加入必要的類型轉換語句
- 加入必要的 bridge method 保證多態的正確性
泛型類的使用-通配符
基本
? 用於在泛型的使用,即爲通配符
通配符-上界
<? extends 上界>
需要區分 泛型使用中的通配符上界 和 泛型定義中的類型上界
通配符-下界
<? super 下界>
泛型中的父子類型
public class MyArrayList { … }
// MyArrayList 不是 MyArrayList 的父類型
// MyArrayList 也不是 MyArrayList 的父類型
// 需要使用通配符來確定父子類型
// MyArrayList<?> 是 MyArrayList<? extends Number> 的父類型
// MyArrayList<? extends Number> 是 MyArrayList 的父類型
泛型方法
定義語法
public class Util {
public static <E> void swap(E[] array, int i, int j) {
E t = array[i];
array[i] = array[j];
array[j] = t;
}
}
方法限定符 <類型形參列表> 返回值類型 方法名稱(形參列表) { … }
泛型的限制
1. 泛型類型參數不支持基本數據類型
2. 無法實例化泛型類型的對象
3. 無法使用泛型類型聲明靜態的屬性
4. 無法使用 instanceof 判斷帶類型參數的泛型類型
5. 無法創建泛型類數組
6. 無法 create、catch、throw 一個泛型類異常(異常不支持泛型)
7. 泛型類型不是形參一部分,無法重載