Java泛型在集合使用與自定義及繼承上的體現(xiàn)和通配符的使用
泛型的概念
集合容器類在設(shè)計階段/聲明階段不能確定這個容器實(shí)際存的是什么類型的對象,所以在JDK1.5之前只能把元素類型設(shè)計為Object,JDK1.5之后使用泛型來解決。因?yàn)檫@個時候除了元素的類型不確定,其他的部分是確定的,例如關(guān)于這個元素如何保存,如何管理等是確定的,因此把元素的類型設(shè)計成一個參數(shù),這個類型參數(shù)叫做泛型。Collection<E>
,ArrayList<E>
中<E>
就是類型參數(shù),即泛型。
所謂泛型,就是允許在定義類、接口時通過一個標(biāo)識表示類中某個屬性的類型或者是某個方法的返回值及參數(shù)類型。這個類型參數(shù)將在使用時(例如,繼承或?qū)崿F(xiàn)這個接口,用這個類型聲明變量、創(chuàng)建對象時)確定(即傳入實(shí)際的類型參數(shù),也稱為類型實(shí)參)。
從JDK1.5以后,Java引入了“參數(shù)化類型(Parameterized type)”的概念,允許在創(chuàng)建集合時再指定集合元素的類型,正如:List<String>
,這表明該List只能保存字符串類型的對象。JDK1.5改寫了集合框架中的全部接口和類,為這些接口、類增加了泛型支持,從而可以在聲明集合變量、創(chuàng)建集合對象時傳入類型實(shí)參。
集合中使用泛型
Collection中使用泛型:
import java.util.ArrayList; import java.util.Iterator; /** * @Author: Yeman * @Date: 2021-09-24-15:10 * @Description: */ public class GenericTest { public static void main(String[] args) { //如下在實(shí)例化的時候在<>中填入需要的類型即可(不可以是基本數(shù)據(jù)類型) ArrayList<Integer> list = new ArrayList<>(); list.add(99); list.add(0); list.add(121); //遍歷方式一 for (Integer integer : list){ System.out.println(integer); } System.out.println("====================="); //遍歷方式二 Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } }
Map中使用泛型:
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * @Author: Yeman * @Date: 2021-09-24-15:10 * @Description: */ public class GenericTest { public static void main(String[] args) { //如下如下在實(shí)例化的時候在<>中填入需要的類型即可(不可以是基本數(shù)據(jù)類型) // 注意因?yàn)镸ap是鍵值對,因此需要分別填入“鍵”和“值”所需要的類型 HashMap<String, Integer> map = new HashMap<>(); map.put("Jack",26); map.put("Marry",18); map.put("Tom",20); map.put("Lily",22); Set<Map.Entry<String, Integer>> entries = map.entrySet(); Iterator<Map.Entry<String, Integer>> iterator = entries.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } }
自定義泛型結(jié)構(gòu)
1、泛型類、泛型接口
①泛型的聲明
interface List<T>{}
、 class GenTest<K,V>{}
、class student <T extends Person> {}
其中,T,K,V不代表值,而是表示類型。這里使用任意字母都可以,常用T表示,是Type的縮寫。
②泛型的實(shí)例化
List<String> strList = new ArrayList<String>();
Iterator<Customer> iterator = customers.iterator();
<>
里面只能是類,不能用基本數(shù)據(jù)類型填充,可以使用包裝類填充。把一個集合中的內(nèi)容限制為一個特定的數(shù)據(jù)類型,這就是Generic的核心思想。
泛型類可能有多個參數(shù),此時可將多個參數(shù)一起放在尖括號內(nèi),如:<E1,E2,E3>
泛型類的構(gòu)造器與非泛型一樣:public GenericClass(){}
,
而public GenericClass<E>(){}
是錯誤的。
泛型不同的引用不能相互賦值:盡管在編譯時ArrayList<String>
和ArrayList<Integer>
是兩種類型,但是,在運(yùn)行時只有一個ArrayList被加載到JVM中。
在類/接口上聲明的泛型,在本類或本接口中即代表某種類型,可以作為非靜態(tài)屬性的類型、非靜態(tài)方法的參數(shù)類型、非靜態(tài)方法的返回值類型。但在靜態(tài)方法中不能使用類的泛型,因?yàn)殪o態(tài)成員是隨著類加載而加載的,而類型的指定是在實(shí)例化時才確定的。
異常類不能使用泛型。
不能new E[]
,但是可以E[] elements = (E[])new Object[capacity];
。
父類有泛型,子類可以選擇保留泛型也可以選擇指定泛型類型,子類除了指定或保留父類的泛型,還可以增加自己的泛型:
class Father<T1, T2> { } // 子類不保留父類的泛型 // 1)沒有類型 擦除 class Son1 extends Father {// 等價于class Son extends Father<Object,Object>{ } // 2)指定類型 class Son2 extends Father<Integer, String> { } // 子類保留父類的泛型 // 1)全部保留 class Son3<T1, T2> extends Father<T1, T2> { } // 2)部分保留 class Son4<T2> extends Father<Integer, T2> { }
class Father<T1, T2> { } // 子類不保留父類的泛型 // 1)沒有類型 擦除 class Son<A, B> extends Father{//等價于class Son extends Father<Object,Object>{ } // 2)具體類型 class Son2<A, B> extends Father<Integer, String> { } // 子類保留父類的泛型 // 1)全部保留 class Son3<T1, T2, A, B> extends Father<T1, T2> { } // 2)部分保留 class Son4<T2, A, B> extends Father<Integer, T2> { }
class Person<T> { // 使用T類型定義變量 private T info; // 使用T類型定義一般方法 public T getInfo() { return info; } public void setInfo(T info) { this.info = info; } // 使用T類型定義構(gòu)造器 public Person() { } public Person(T info) { this.info = info; } }
2、泛型方法
方法,也可以被泛型化,不管此時定義在其中的類是不是泛型類。在泛型方法中可以定義泛型參數(shù),此時,參數(shù)的類型就是傳入數(shù)據(jù)的類型。
訪問權(quán)限 是否為靜態(tài) <泛型> 返回類型 方法名(泛型標(biāo)識 參數(shù)名稱,...) 異常{ //方法體 }
public class Test { public <E> E get(int id, E[] arry) { E result = null; return result; } }
泛型在繼承上的體現(xiàn)
如果B是A的一個子類型(子類或者子接口),而G是具有泛型聲明的類或接口,G<B>
并不是G<A>
的子類型!比如:String是Object的子類,但是List<String>
并不是List<Object>
的子類,不能相互賦值。而反過來,如下是可以的:
ArrayList<String> arrayList = new ArrayList<>(); List<String> list = arrayList;
通配符的使用
1、使用
比如:List<?>
,Map<?,?>
,
List<?>
是List<String>
、List<Object>
等各種泛型List的父類。
讀取List<?>
的對象list中的元素時,永遠(yuǎn)是安全的,因?yàn)椴还躭ist的真實(shí)類型是什么,都包含于Object。而不能向其中添加(寫入)對象。除了null,因?yàn)樗撬蓄愋偷某蓡T:
Collection<?> c = new ArrayList<String>(); c.add(new Object()); // 編譯時錯誤
public static void main(String[] args) { List<?> list = null; list = new ArrayList<String>(); list = new ArrayList<Double>(); list.add(3);//編譯不通過,編譯時錯誤 list.add(null); List<String> l1 = new ArrayList<String>(); List<Integer> l2 = new ArrayList<Integer>(); l1.add("AABBCC"); l2.add(9); read(l1); read(l2); } public static void read(List<?> list) { for (Object o : list) { System.out.println(o); } }
2、有限制的通配符
①<?>
允許所有泛型的引用調(diào)用
②通配符指定上限
extends:使用時指定的類型必須是繼承某個類,或者實(shí)現(xiàn)某個接口,即<=。
<? extends Number>
(無窮小 , Number],只允許泛型為Number及Number子類的引用調(diào)用。<? extends Comparable>
只允許泛型為實(shí)現(xiàn)Comparable接口的實(shí)現(xiàn)類的引用調(diào)用。
③通配符指定下限
下限super:使用時指定的類型不能小于操作的類,即>=。
<? super Number>
[Number , 無窮大),只允許泛型為Number及Number父類的引用調(diào)用。
到此這篇關(guān)于Java泛型在集合使用與自定義及繼承上的體現(xiàn)和通配符的使用的文章就介紹到這了,更多相關(guān)Java 泛型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java多線程使用阻塞隊列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型詳解
這篇文章主要介紹了Java多線程使用阻塞隊列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型詳解,主要講解阻塞隊列的特性、實(shí)際開發(fā)中常用的到的生產(chǎn)者消費(fèi)者模型,以及生產(chǎn)者消費(fèi)者模型解耦合、削峰填谷的好處,需要的朋友可以參考下2023-07-07SVN報錯:Error Updating changes:svn:E155037的解決方案
今天小編就為大家分享一篇關(guān)于SVN報錯:Error Updating changes:svn:E155037的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01Mybatis中的PageHelper的執(zhí)行流程分析
這篇文章主要介紹了Mybatis的PageHelper執(zhí)行流程,本文給大家介紹介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02java開發(fā)微服務(wù)架構(gòu)設(shè)計消息隊列的水有多深
今天我們說說消息隊列的問題,來帶大家探一探消息隊列的水有多深,希望看完本文大家在引入消息隊列的時候先想一想,是不是一定要引入?引入消息隊列后產(chǎn)生的問題能不能解決2021-10-10spring boot中的properties參數(shù)配置詳解
這篇文章主要介紹了spring boot中的properties參數(shù)配置,需要的朋友可以參考下2017-09-09Springboot全局異常捕獲及try catch區(qū)別解析
這篇文章主要介紹了Springboot全局異常捕獲及try catch區(qū)別解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06