本篇文章給大家?guī)砹岁P(guān)于java的相關(guān)知識,其中主要介紹了關(guān)于泛型的相關(guān)問題,包括了自定義泛型類、自定義泛型方法、自定義泛型接口等等內(nèi)容,下面一起來看一下,希望對大家有幫助。
推薦學(xué)習(xí):《java視頻教程》
- 泛型:是JDK5中引入的特性,可以在編譯階段約束操作的數(shù)據(jù)類型,并進(jìn)行檢查。
- 泛型的格式:<數(shù)據(jù)類型>,注意:泛型只能支持引用數(shù)據(jù)類型。
- 集合體系的全部接口和實(shí)現(xiàn)類都是支持泛型的使用的。
優(yōu)點(diǎn):
- 統(tǒng)一數(shù)據(jù)類型。
- 把運(yùn)行的問題提前到編譯期間,避免了強(qiáng)制類型轉(zhuǎn)換可能出現(xiàn)的問題,因?yàn)榫幾g階段類型便可以確定下來。
public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("石原里美"); list.add("工藤靜香"); list.add("朱茵"); for (String s : list) { System.out.println(s); } } 輸出結(jié)果: 石原里美 工藤靜香 朱茵
并且泛型還可以在很多地方進(jìn)行定義,比如在類后面就是泛型類、方法聲明上就是泛型方法、接口后面就是泛型接口。接下來我們共同來學(xué)習(xí)一下這些泛型是如何使用的:
自定義泛型類
概念
- 定義類的同時定義了泛型的類就是泛型類。
- 泛型類的格式:修飾符 class 類名<泛型變量> { }
public class MyArrayList<E>{ }
- 作用:編譯階段可以指定數(shù)據(jù)類型,類似于集合的作用
實(shí)戰(zhàn)教學(xué)
現(xiàn)創(chuàng)建一個泛型類,實(shí)現(xiàn)基本的增加、刪除操作,以此來具體了解其用法:
//泛型類MyArrayLIst public class MyArrayLIst<E> { public void add(E e){ } public void remove(E e){ } } //main public static void main(String[] args) { MyArrayLIst<String> list = new MyArrayLIst<>(); //通過對泛型的設(shè)定,實(shí)現(xiàn)對數(shù)據(jù)專一處理 list.add("石原里美"); list.add("工藤靜香"); list.remove("工藤靜香"); }
泛型類的原理:
把出現(xiàn)泛型變量的地方全部替換成傳輸?shù)恼鎸?shí)的數(shù)據(jù)類型。
通過認(rèn)真觀察,其實(shí)不難去發(fā)現(xiàn),泛型類與普通類的最大區(qū)別在于在調(diào)用方法的時候可以統(tǒng)一的對同一種數(shù)據(jù)進(jìn)行處理,不會涉及到其他的數(shù)據(jù)類型,從一定程度上避免了強(qiáng)制類型轉(zhuǎn)化時可能會出現(xiàn)的問題。
自定義泛型方法
概念
- 定義方法的同時定義了泛型的方法就是泛型方法。
- 泛型方法的格式:修飾符<泛型變量> 返回值類型 方法名(形參列表){ }
public <E> void view(E e){ }
- 作用:方法中可以使用泛型接收一切實(shí)際類型的參數(shù),方法更具備通用性。
- 注意:泛型方法需要區(qū)別于泛型類中所定義的方法,雖然它們也在使用泛型,但是該泛型不是其定義的,而是泛型類定義的。
實(shí)戰(zhàn)教學(xué)
無論傳入何種類型的數(shù)組,都可以返回它的內(nèi)容,即實(shí)現(xiàn)Arrays.toString()的作用
public static void main(String[] args) { String [] name = {"石原里美","工藤靜香","朱茵"}; view(name); Integer [] age = {18,19,20}; view(age); } public static <T> void view(T[] arr){ StringBuilder list = new StringBuilder(); for (int i = 0; i < arr.length; i++) { list.append(arr[i]).append("t"); } System.out.println(list); }
通過實(shí)現(xiàn)對泛型方法的定義,可以實(shí)現(xiàn)多種數(shù)據(jù)類型的接收,應(yīng)用范圍更加廣泛。
自定義泛型接口
概念
- 使用泛型定義的接口就是泛型接口。
- 泛型接口的格式:public interface People<E>{ }
public interface People <E>{ }
- 作用:泛型接口可以讓實(shí)現(xiàn)類選擇當(dāng)前功能需要操作的數(shù)據(jù)類型
實(shí)戰(zhàn)教學(xué)
定義一個People接口,實(shí)現(xiàn)對老師Teacher類、學(xué)生Student等類的操作
//People接口 public interface People <E>{ void run(E e); void height(E e); } //Student類 public class Teacher { } //實(shí)現(xiàn)類Fantype public class Fantype implements People<Teacher> { @Override public void run(Teacher teacher) { } @Override public void height(Teacher teacher) { } }
通過對上述代碼的觀察,可以發(fā)現(xiàn),People后定義的是什么類型,那么該實(shí)現(xiàn)類只能對該種數(shù)據(jù)類型進(jìn)行操作,其他類型不可以進(jìn)行此操作。
通配符和上下限
通配符
- ?可以在“使用泛型”的時候代表一切類型
- E T K V是在定義泛型的時候用的
假設(shè)現(xiàn)在有一場為學(xué)生和老師而舉辦的比賽,需要比較速度究竟誰更快,分別創(chuàng)建一定數(shù)量的對象并將其傳入集合之中。然而當(dāng)我們將這兩個集合分別傳入方法中的時候,會發(fā)現(xiàn),學(xué)生對象集合list2出現(xiàn)報錯,為什么呢?原因是因?yàn)閿?shù)據(jù)類型不同,那么該如何使得兩種類型都可以傳入呢?或許這個時候就會有人說了:“既然兩個類都是People的子類,那么為什么不定義它的泛型是People呢?”這個想法很好,但是我們需要明確一點(diǎn)的是子類與父類雖然是有關(guān)系的,但是定義之后的集合是沒有關(guān)系的,所以這里是行不通的。
//main //老師對象集合 ArrayList<Teacher> list1 = new ArrayList<>(); list1.add(new Teacher()); list1.add(new Teacher()); pk(list1); //學(xué)生對象集合 ArrayList<Student> list2 = new ArrayList<>(); list2.add(new student()); list2.add(new student()); pk(list2);//由于pk方法的形參是泛型為Teacher的集合,所以會報錯 //父類 class People{ } //子類 class Teacher extends People{ } class student extends People{ } //pk方法: public static void pk(ArrayList<Teacher> people){ }
應(yīng)對這個問題,我們可以便可以將本篇文章引入的知識“通配符”放在實(shí)際應(yīng)用中解決問題了,通過其簡短的概念“?可以在‘使用泛型’的時候代表一切類型”就可以理解其作用了,這里我們可以使用“?”共同代表兩種類型。
public static void pk(ArrayList<?> people){ //通過通配符?便可以將這個問題解決掉 }
上下限
然而此時又出現(xiàn)一個問題,定義了一個dog類,試圖創(chuàng)建一些對象并傳入集合中混入比賽,這種當(dāng)然情況當(dāng)然是不允許發(fā)生的,然而?是可以表示任意類型的,并不能對其進(jìn)行限制。因此上下限的作用就體現(xiàn)出來了:
- 上限:<? extends 父類>,傳入類型必須是該父類或者是父類的子類
- 下限:<? super 子類>,傳入類型必須是該子類或者是子類的父類
public static void pk(ArrayList<? extends People> people){ //通過上下限便可以將這個問題解決掉 //要求傳入的類型必須是People的子類才可以 }
推薦學(xué)習(xí):《java視頻教程》