1.泛型應用
- 泛型類
- 泛型方法
- 泛型接口
1.1 泛型類
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
說明:
1.在類上定義的泛型,當外界在創建這個類的對象的時候,需要創建者自己來明確當前泛型的具體類型;
2.在類上定義的泛型,在類中的方法上和成員變量是可以使用的;
3.創建類的對象時沒有指定泛型類的類型時,那麼ABC默認是Object類型;
好處:
在使用的時候,不用強轉了(沒有轉換時問題了),會自動轉成成用戶想要的類型
public static void main(String[] args) {
//創建對象並指定元素類型
ObjectTool<String> tool = new ObjectTool<>();
tool.setObj(new String("鍾福成"));
String s = tool.getObj();
System.out.println(s);
//創建對象並指定元素類型
ObjectTool<Integer> objectTool = new ObjectTool<>();
/**
* 如果我在這個對象裏傳入的是String類型的,它在編譯時期就通過不了了.
*/
objectTool.setObj(10);
int i = objectTool.getObj();
System.out.println(i);
}
1.2 泛型方法
在函數上使用泛型的格式:
函數修飾符 <泛型名> 函數返回值類型 方法名( 泛型名 變量名 )
{
函數體;
}
說明:
1.public和返回值/void中間的<Q>非常重要,可以理解爲聲明此方法爲泛型方法
2.只有聲明瞭方法纔是泛型方法,泛型類中使用了泛型的成員方法並不是泛型方法
3.表明該方法將使用泛型類型Q,此時才能在方法中使用泛型類型Q
4.與泛型類的定義一樣,此處Q可以隨意寫爲任意標識,常見的T,E,K,V等形式的參數常用於表示泛型
注意:
1.方法上的泛型和類上的泛型無關
2.類上的泛型在創建這個類的時候確定,而方法上的泛型在調用這個方法時確定
靜態函數上的泛型:
靜態函數不能使用類上定義的泛型
因爲靜態方法的運行是不需要對象的,而類上的泛型必須在創建這個類對象的時候才能明確具體是什麼類型
而靜態函數運行的時候是沒有對象的,也就是說類上的泛型在靜態函數運行的時候還不知道是什麼類型
1.3 泛型接口
泛型接口的格式:
修飾符 interface 接口名<泛型>{}
什麼時候確定泛型的類型呢?有兩種方式可以實現。
方式1:類實現接口的時候,直接明確泛型類型。
方式2:類實現接口的時候,還不確定數據類型,這時可以在實現類上隨便先定義個泛型,當這個類被創建對象的時候,就明確了類上的泛型,於是接口上的泛型也明確了。
1.4 泛型通配符
通配符往往能提供給我們比不可變類型更多的靈活性。例如:
public static void main(String[] args) {
List<Number> list1 = new ArrayList<Number>();
List<Long> list2 = new ArrayList<Long>();
List<String> list3 = new ArrayList<String>();
f(list1);
f(list2);
f(list3);
}
public static void f(List<?> list) { }
邊界
- 使用子類通配符<? extends xx>
- 父類通配符<? super xx>
public static void main(String[] args) {
List<Number> list1 = new ArrayList<Number>();
List<Long> list2 = new ArrayList<Long>();
List<String> list3 = new ArrayList<String>();
f(list1);
f(list2);
f(list3); //編譯錯誤
}
public static void f(List<? extends Number> list) { }
<? extends Number>表示匹配Number及其子類類型,故String類型匹配錯誤
public static void main(String[] args) {
List<Number> list1 = new ArrayList<Number>();
List<Long> list2 = new ArrayList<Long>();
List<String> list3 = new ArrayList<String>();
f(list1);
f(list2); //編譯錯誤
f(list3); //編譯錯誤
}
public static void f(List<? super Number> list) { }
<? super Number>表示匹配Number及其父類類型,故Long和String類型匹配錯誤