本篇內(nèi)容介紹了“如何快速了解泛型”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到柴桑網(wǎng)站設(shè)計(jì)與柴桑網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:成都網(wǎng)站建設(shè)、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名與空間、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋柴桑地區(qū)。
一、初識(shí)泛型
在沒(méi)有泛型的出現(xiàn)之前,我們通常是使用類(lèi)型為 Object 的元素對(duì)象。比如我們可以構(gòu)建一個(gè)類(lèi)型為 Object 的集合,該集合能夠存儲(chǔ)任意數(shù)據(jù)類(lèi)型的對(duì)象,但是我們從集合中取出元素的時(shí)候我們需要明確的知道存儲(chǔ)每個(gè)元素的數(shù)據(jù)類(lèi)型,這樣才能進(jìn)行元素轉(zhuǎn)換,不然會(huì)出現(xiàn) ClassCastException 異常。
1. 什么是泛型
泛型是在 Java1.5 之后引入的一個(gè)新特性,它特性提供了編譯時(shí)類(lèi)型安全監(jiān)測(cè)機(jī)制,該機(jī)制允許我們?cè)诰幾g時(shí)監(jiān)測(cè)出非法的類(lèi)型數(shù)據(jù)結(jié)構(gòu)。
它的本質(zhì)就是參數(shù)化類(lèi)型,也就是所操作的數(shù)據(jù)類(lèi)型被指定為一個(gè)參數(shù)。這種參數(shù)類(lèi)型可以用在 類(lèi)、接口和方法 中,分別被稱(chēng)為 泛型類(lèi)、泛型接口和泛型方法
2. 使用好處
類(lèi)型安全
有了泛型的存在,只要編譯時(shí)沒(méi)有出現(xiàn)警告,那么運(yùn)行時(shí)就不會(huì)出現(xiàn) ClassCastException 異常。
消除強(qiáng)制類(lèi)型轉(zhuǎn)換
從泛型集合中取出元素我們可以不用進(jìn)行類(lèi)型的轉(zhuǎn)換
可讀性更高
可以直接看出集合中存放的是什么數(shù)據(jù)類(lèi)型的元素
二、泛型的使用
1. 使用場(chǎng)景
1)泛型類(lèi)
基本語(yǔ)法
class 類(lèi)名稱(chēng) <泛型標(biāo)識(shí),泛型標(biāo)識(shí),…> { private 泛型標(biāo)識(shí) 變量名; ..... }
使用示例
class Result<T>{ private T data; }
注:
Java 1.7 之后可以進(jìn)行類(lèi)型推斷,后面 <> 中的具體的數(shù)據(jù)類(lèi)型可以省略不寫(xiě):
類(lèi)名<具體的數(shù)據(jù)類(lèi)型> 對(duì)象名 = new 類(lèi)名<>();
如果我們使用的時(shí)候沒(méi)有用到 <> 來(lái)制定數(shù)據(jù)類(lèi)型,那么操作類(lèi)型則是 Object
泛型內(nèi)的類(lèi)型參數(shù)只能是類(lèi) 類(lèi)型,而不能是基本數(shù)據(jù)類(lèi)型,例如int,double,float...
當(dāng)我們傳入不同數(shù)據(jù)類(lèi)型進(jìn)行構(gòu)造對(duì)象時(shí),邏輯上可以看成是多個(gè)不同的數(shù)據(jù)類(lèi)型,但實(shí)際上都是相同類(lèi)型
以上便是泛型類(lèi)的簡(jiǎn)單用法,我們想要使用哪種類(lèi)型,就在創(chuàng)建的時(shí)候指定類(lèi)型,使用的時(shí)候,該類(lèi)就會(huì)自動(dòng)轉(zhuǎn)換成用戶(hù)想要使用的類(lèi)型。
那么如果我們定義了一個(gè)泛型類(lèi),構(gòu)造對(duì)象的時(shí)候卻沒(méi)有聲明數(shù)據(jù)類(lèi)型,那么默認(rèn)為 Object 類(lèi)型,取出數(shù)據(jù)的時(shí)候則需要進(jìn)行類(lèi)型轉(zhuǎn)換:
Result objectRes = new Result("testObejct"); String str = (String) objectRes.getData(); System.out.println(str);
規(guī)則:
子類(lèi)也是泛型類(lèi),那么子類(lèi)和父類(lèi)的泛型類(lèi)型要一致
public class ResultChild<T> extends Result<T> {}
子類(lèi)不是泛型類(lèi),那么父類(lèi)要指定數(shù)據(jù)類(lèi)型
public class ResultChild extends Result<String> {}
2)泛型接口
基本語(yǔ)法
public 接口名稱(chēng) <泛型標(biāo)識(shí), 泛型標(biāo)識(shí), ...>{ 泛型標(biāo)識(shí) 方法名(); ... }
使用示例
public interface ResultInterface<T> { T getData(); }
泛型接口與泛型類(lèi)一樣,有以下規(guī)則:
實(shí)現(xiàn)類(lèi)不是泛型類(lèi),接口要明確數(shù)據(jù)類(lèi)型
實(shí)現(xiàn)類(lèi)也是泛型類(lèi),實(shí)現(xiàn)類(lèi)和接口的泛型類(lèi)型要一致
3)泛型方法
在 Java 中,泛型類(lèi)和泛型接口的定義相對(duì)比較簡(jiǎn)單,但是 泛型方法 就比較復(fù)雜。
泛型類(lèi),是在實(shí)例化類(lèi)的時(shí)候指明泛型的具體類(lèi)型
泛型方法,是在調(diào)用方法的時(shí)候指明泛型的具體類(lèi)型
基本語(yǔ)法
修飾符 <T, E, ...> 返回值類(lèi)型 方法名(形參列表){}
修飾符與返回值類(lèi)型之間的<T>
只有聲明了<T>
使用示例
private <T> Result<T> getResult(T data) { return new Result<T>(data); }
泛型方法與可變參數(shù):
private <T> void printData(T... data) { for (T t : data) { System.out.println(t); } }
注:
泛型方法能使方法獨(dú)立于類(lèi)而產(chǎn)生變化
如果 靜態(tài)(static) 方法 要使用泛型能力,就必須使其成為泛型方法
2. 類(lèi)型通配符
1)什么是類(lèi)型通配符
類(lèi)型通配符一般使用 " ? " 代替具體的實(shí)參類(lèi)型
類(lèi)型通配符是 實(shí)參類(lèi)型 ,而不是 形參類(lèi)型
類(lèi)型通配符又分為 類(lèi)型通配符的上限 和 類(lèi)型通配符的下限
2)基本語(yǔ)法
類(lèi)型通配符的上限:
類(lèi)/接口<? extends 實(shí)參類(lèi)型>
類(lèi)/接口
注:要求該泛型的類(lèi)型,只能是實(shí)參類(lèi)型,或?qū)崊㈩?lèi)型的 子類(lèi) 類(lèi)型
類(lèi)型通配符的下限:
類(lèi)/接口<? super 實(shí)參類(lèi)型>
注:要求該泛型的類(lèi)型,只能是實(shí)參類(lèi)型,或?qū)崊㈩?lèi)型的 父類(lèi) 類(lèi)型
2)使用示例
類(lèi)型通配符的上限:
如果我們要打印一個(gè) List 的值,我們可能會(huì)這么做:
private void printData(List list) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } }
看上去沒(méi)啥問(wèn)題,但是又覺(jué)得怪怪的。因?yàn)檫@就跟黑匣子一樣,我根本不知道這個(gè) List 里面裝的是什么類(lèi)型的參數(shù)。那我們就在傳參的時(shí)候定義一下類(lèi)型:
private void printData(List<Object> list) { for (Object o : list) { System.out.println(o); } }
但是這樣定義又太廣泛了,Object 是所有類(lèi)型的父類(lèi),如果說(shuō)我想這個(gè)方法只能操作數(shù)字類(lèi)型的元素,那我就能用上 類(lèi)型通配符的上限 來(lái)解決這個(gè)問(wèn)題了:
private void printData(List<? extends Number> numList) { for (Number number : numList) { System.out.println(number); } }
但我們需要使用這個(gè)方法時(shí)候我們就很直觀(guān)的可以看出來(lái),這個(gè)方法傳的實(shí)參只能是 Number 的子類(lèi)。
printData(Arrays.asList(1, 2, 3)); printData(Arrays.asList(1L, 2L, 3L));
類(lèi)型通配符的下限:
上面我們了解到 類(lèi)型通配符上限的使用 ,那么 類(lèi)型通配符上限 是如何使用的?
類(lèi)型通配符上限 在我們平時(shí)開(kāi)發(fā)中使用的頻率也相對(duì)較少。編譯器只知道集合元素是下限的父類(lèi)型,但具體是哪一種父類(lèi)型是不確定的。因此,從集合中取元素只能被當(dāng)成Object類(lèi)型處理(編譯器無(wú)法確定取出的到底是哪個(gè)父類(lèi)的對(duì)象)。
我們可以自定義一個(gè)復(fù)制集合的函數(shù):
首先定義兩個(gè)類(lèi):
public class Animal { } public class Pig extends Animal{ }
定義一個(gè)復(fù)制函數(shù):
private static <T> Collection<? super T> copy(Collection<? super T> parent, Collection<T> child) { for (T t : child) { parent.add(t); } return parent; }
使用:
List<Animal> animals = new ArrayList<>(); List<Pig> pigs = new ArrayList<>(); pigs.add(new Pig()); pigs.add(new Pig()); copy(animals,pigs); System.out.println(animals);
3. 類(lèi)型擦除
因?yàn)榉盒托畔⒅淮嬖谟诖a編譯階段,所以在進(jìn)入 JVM 之前,會(huì)把與泛型相關(guān)的信息擦除,這就稱(chēng)為 類(lèi)型擦除
1)無(wú)限制類(lèi)型擦除
類(lèi)型擦除前:
public class Result<T>{ private T data; }
類(lèi)型擦除后:
public class Result{ private Object data; }
2)有限制類(lèi)型擦除
類(lèi)型擦除前:
public class Result<T extends Number>{ private T data; }
類(lèi)型擦除后:
public class Result{ private Number data; }
3)擦除方法中類(lèi)型定義的參數(shù)
類(lèi)型擦除前:
private <T extends Number> T getValue(T value){ return value; }
類(lèi)型擦除后:
private Number getValue(Number value){ return value; }
“如何快速了解泛型”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
網(wǎng)站標(biāo)題:如何快速了解泛型
文章位置:http://jinyejixie.com/article28/pgihjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、商城網(wǎng)站、網(wǎng)站制作、靜態(tài)網(wǎng)站、移動(dòng)網(wǎng)站建設(shè)、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)