泛型
一、泛型概述
- 泛型是 JDK5 中引入的特性,它提供了編譯時類型安全檢測機制,該機制允許在編譯時檢測到非法的類型,它的本質是 參數化類型,也就是說所操作的數據類型被指定為一個參數
- 定義方法時有形參,然後調用此方法時傳遞實參,參數化類型就是 將類型由原來的具體的類型參數化,然後在使用、調用時傳入具體的引用數據類型
- 這種參數類型可以用在類、方法和接口中,分別被稱為泛型類、泛型方法、泛型接口,好處是把運行時期的問題提前到了編譯期間,避免了強制類型轉換
二、泛型類
格式: 修飾符 class 類名<類型>{ }
範例: public class Generic{ }
注意: 此處 T 可以隨便寫為任意標識,常見的如 T、E、K、V 等形式的參數常用於表示泛型
代碼示例
// 泛型類
public class Generic<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
// 泛型類測試
public class Test {
public static void main(String[] args) {
// 指定String類型
Generic<String> g1 = new Generic<>();
g1.setT("孫悟空");
System.out.println("t = " + g1.getT());
// 指定Integer類型
Generic<Integer> g2 = new Generic<>();
g2.setT(500);
System.out.println("t = " + g2.getT());
// 指定其它類型...
}
}
t = 孫悟空
t = 500
三、泛型方法
格式: 修飾符 <類型> 返回值類型 方法名(類型 變量名) { }
範例: public void show(T t) { }
代碼示例
public class Generic {
// 泛型方法,若需返回值,則將void也改為T
public <T> void show(T t) {
System.out.println("t = " + t);
}
}
// 泛型方法測試
public class Test {
public static void main(String[] args) {
Generic g = new Generic();
// 傳入String類型
g.show("孫悟空");
// 傳入int類型
g.show(500);
// 傳入其它類型...
}
}
t = 孫悟空
t = 500
四、泛型接口
格式: 修飾符 interface 接口名<類型> { }
範例: public interface Generic { }
代碼示例
// 泛型接口
public interface Generic<T> {
void show(T t);
}
// 泛型接口實現類
public class GenericImpl<T> implements Generic<T> {
@Override
public void show(T t) {
System.out.println("t = " + t);
}
}
//泛型接口實現類測試
public class Test {
public static void main(String[] args) {
// 指定String類型
GenericImpl<String> g1 = new GenericImpl<>();
g1.show("孫悟空");
// 指定Integer類型
GenericImpl<Integer> g2 = new GenericImpl<>();
g2.show(500);
// 指定其它類型...
}
}
t = 孫悟空
t = 500
五、類型通配符
-
類型通配符:<?>
- List<?>: 表示元素類型未知的 List,它的元素可以匹配 任何的類型,List 僅表示它是各種泛型 List 的父類,並不能把元素添加到其中
-
類型通配符上限:<? extends 類型>
- List<? extends Number>: 它表示的類型是 Number 或者其子類型
-
類型通配符下限:<? super 類型>
- List<? super Number>: 它表示的類型是 Number 或者其父類型
代碼示例
// 類型通配符測試
public class Test {
public static void main(String[] args) {
// 類型通配符:<?>
// 表示元素類型未知的List,它的元素可以匹配任何的類型
List<?> l1 = new ArrayList<Object>();
List<?> l2 = new ArrayList<>();
List<?> l3 = new ArrayList<>();
// 類型通配符上限:<? extends 類型>
// 表示Number或者其子類型
List<? extends Number> l4 = new ArrayList<Number>();
List<? extends Number> l5 = new ArrayList<Integer>();
//List<? extends Number> l6 = new ArrayList<String>(); //報錯
// 類型通配符下限:<? super 類型>
// 表示的類型是Number或者其父類型
List<? super Number> l7 = new ArrayList<Number>();
List<? super Number> l8 = new ArrayList<Object>();
//List<? super Number> l9 = new ArrayList<Integer>(); //報錯
}
}
六、可變參數
可變參數又稱參數個數可變,用作方法的形參出現
格式: 修飾符 返回值類型 方法名(數據類型… 變量名) { }
範例: public static int sum(int… a) { }
注意: 這裡的變量其實是一個數組,若一個方法有多個參數,包含可變參數,可變參數要放在最後
代碼示例
// 可變參數測試
public class Test {
public static void main(String[] args) {
System.out.println(sum(10, 20));
System.out.println(sum(10, 20, 30));
System.out.println(sum(10, 20, 30, 40));
}
public static int sum(int... num) {
int sum = 0;
for (int i : num) {
sum += i;
}
return sum;
}
}
30
60
100