泛型是一種數據類型,當我們不知道使用什么數據類型是,可以使用泛型。 泛型也可以看出一個變量,用來接收數據類型。
E e :Element 元素
T t :Type 類型
如:
ArrayList集合在定義的時候,不知道集合都會存儲什么類型的數據,所以使用泛型:
E :未知的數據類型
什么時候確定泛型的數據類型呢?
答:創建集合對象的時候,就會確定泛型的數據類型
ArrayList<String> list = new Arraylist<>(); public class ArrayList<E>{ public boolean add(E e){} public E get(int index){} }
//創建集合對象的時候,就會確定泛型的數據類型
public class Arraylist<String>{ public boolean add(String s){} public String get(int index){} }
我們在集合中會大量使用到泛型,這里來完整地學習泛型知識。
-
泛型,用來靈活地將數據類型應用到不同的類、方法、接口當中。
-
將數據類型作為參數進行傳遞。
定義和使用含有泛型的類
定義語法格式:
修飾符 class 類名<代表泛型的變量> { //方法體 }
例如,API中的ArrayList集合:
class ArrayList<E>{ public boolean add(E e){ } public E get(int index){ } .... }
使用泛型: 即什么時候確定泛型。
在創建對象的時候確定泛型
例如,
ArrayList<String> list = new ArrayList<String>();
此時,變量E的值就是String類型,那么我們的類型就可以理解為:
class ArrayList<String>{ public boolean add(String e){ } public String get(int index){ } ... }
泛型通配符
當使用泛型類或者接口時,傳遞的數據中,泛型類型不確定,可以通過通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object類中的共性方法,集合中元素自身方法無法使用。
通配符基本使用
泛型的通配符:不知道使用什么類型來接收的時候,此時可以使用?,?表示未知通配符。
此時只能接受數據,不能往該集合中存儲數據。
通配符高級使用----受限泛型
之前設置泛型的時候,實際上是可以任意設置的,只要是類就可以設置。但是在JAVA的泛型中可以指定一個泛型的上限和下限。
泛型的上限:
-
格式:
類型名稱 <? extends 類 > 對象名稱
-
意義:
只能接收該類型及其子類
泛型的下限:
-
格式:
類型名稱 <? super 類 > 對象名稱
-
意義:
只能接收該類型及其父類型
比如:現已知Object類,String 類,Number類,Integer類,其中Number是Integer的父類
public class DemoGeneric { public static void main(String[] args) { Collection<Integer> list1 = new ArrayList<Integer>(); Collection<String> list2 = new ArrayList<String>(); Collection<Number> list3 = new ArrayList<Number>(); Collection<Object> list4 = new ArrayList<Object>(); getElement1(list1); // getElement1(list2);//報錯 String類與Number類沒有繼承關系,因此泛型沒有受限一說 getElement1(list3); // getElement1(list4);//報錯 Object類是Number類的父類,因此不能使用泛型上限 // getElement2(list1);//報錯 // getElement2(list2);//報錯 getElement2(list3); getElement2(list4); /* 類與類之間的繼承關系: Integer extends Number extends Object String extends Object */ } // 泛型的上限:此時的泛型?,必須是Number類型或者Number類型的子類 public static void getElement1(Collection<? extends Number> coll) { } // 泛型的下限:此時的泛型?,必須是Number類型或者Number類型的父類 public static void getElement2(Collection<? super Number> coll) { } }
泛型總結
1、泛型類和泛型方法
定義語法格式:
權限修飾符 class 類名<泛型>{}
權限修飾符 返回值類型 方法名(泛型作為參數傳遞){}
2、泛型接口和泛型方法
定義語法格式:
接口:權限修飾符 interface 接口名稱<泛型>{}
實現類: 權限修飾符 class 類名<泛型> implement 接口名<泛型>{}
權限修飾符 返回值類型 方法名(泛型作為參數傳遞){}
3、泛型通配符
package _4泛型的概念和使用._4泛型的高級使用$泛型的受限$上限_下限; import java.util.ArrayList; import java.util.Collection; /** * @Author Admin * @Classname DemoGeneric * @Package _4泛型的概念和使用._4泛型的高級使用$泛型的受限$上限_下限 * @GreatDate 2020/04/17 21:56:07 * @Description TODO 泛型的高級使用,泛型的受限(上、下限限定) */ /* 泛型的受限 上限限定:? extends E;代表使用的泛型只能是E類型的子類/本身 下限限定:? super E: 代表使用的泛型只能是E類型的父類/本身 */ public class DemoGeneric { public static void main(String[] args) { Collection<Integer> list1 = new ArrayList<Integer>(); Collection<String> list2 = new ArrayList<String>(); Collection<Number> list3 = new ArrayList<Number>(); Collection<Object> list4 = new ArrayList<Object>(); getElement1(list1); //getElement1(list2);//報錯 getElement1(list3); //getElement1(list4);//報錯 //getElement2(list1);//報錯 //getElement2(list2);//報錯 getElement2(list3); getElement2(list4); } /* 類生類之間的繼承關系 Integer extends Number extends Object String extends 0bject */ // 泛型的上限:此時的泛型?,必須是Number類型或者Number類型的子類 public static void getElement1(Collection<? extends Number> coll){} // 泛型的下限:此時的泛型?,必須是Number類型或者Number類型的父類 public static void getElement2(Collection<? super Number> coll){} }