最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳細(xì)全面解析Java泛型

 更新時(shí)間:2022年02月07日 10:21:29   作者:Faith_xzc  
這篇文章主要介紹了詳細(xì)全面解析Java泛型,java泛型主要提高了Java 程序的類型安全,通過知道使用泛型定義的變量的類型限制,編譯器可以驗(yàn)證類型假設(shè),消除源代碼中的許多強(qiáng)制類型轉(zhuǎn)換等多個(gè)有點(diǎn),下面我們進(jìn)入文章了解更多的詳細(xì)內(nèi)容吧

1.概述

作為一個(gè)面向?qū)ο蟮木幊陶Z言,Java可以通過實(shí)現(xiàn)一些類,作為我們各種需求的一個(gè)模板,方便我們的使用。但有時(shí)候,這個(gè)類的范圍可能比我們想要的范圍要大,我們只想限定于滿足類的某些對象,那這樣的情況下,泛型的概念就被提出來了(非官方解釋,方便理解)。

舉個(gè)例子:比如我們我們生活中的車,它可以作為一個(gè)類,但是車其實(shí)又有很多種,包括貨車,轎車,大巴車等等,而其中的轎車外觀差不多,但是又屬于不同的品牌,這些品牌有很多不一樣的地方,這里我們可以把轎車的品牌看作是泛型(類似于標(biāo)簽)

通過上面的解釋,泛型的概念就比較清晰了,就是一種“類型參數(shù)”,所謂類型參數(shù)可以理解為將類型由原來的具體的類型進(jìn)行參數(shù)化,類似于方法中的變量參數(shù),此時(shí)類型也定義成參數(shù)形式(可以稱之為類型形參),然后在使用/調(diào)用時(shí)傳入具體的類型(類型實(shí)參)。

泛型的優(yōu)點(diǎn),不僅僅是上面提到的,其還有下面的優(yōu)點(diǎn)::

類型安全: 提高Java 程序的類型安全(泛型的主要目標(biāo))。
通過知道使用泛型定義的變量的類型限制,編譯器可以驗(yàn)證類型假設(shè)。
消除強(qiáng)制類型轉(zhuǎn)換:消除源代碼中的許多強(qiáng)制類型轉(zhuǎn)換。
這使得代碼的可讀性更高了,并且還減少了錯(cuò)誤
上面說到了泛型在類中的使用,其實(shí)泛型的使用遠(yuǎn)不止于此,其還可以在在接口、方法中使用。下面就對這些分別進(jìn)行介紹

2.泛型類

所謂泛型類就是把當(dāng)我們在聲明類時(shí),類中的有些成員的類型并不是確定,然后我們可以把泛型定義在類上,當(dāng)使用該類的時(shí)候,再把不確定成員的類型明確下來。

語法格式:

【修飾符】 class 類名<類型變量列表>{
    //類體
}

注: <類型變量列表>:可以是一個(gè)或多個(gè)類型變量,一般都是使用單個(gè)的大寫字母表示。例如:、<K,V>等。

<類型變量列表>中的類型變量不能用于靜態(tài)成員上。

泛型類的使用:

使用這種類似于參數(shù)化類型的類時(shí),在創(chuàng)建類的對象時(shí)候,我們需要注意:

  • 指定類型變量對應(yīng)的實(shí)際類型參數(shù)
  • 實(shí)際類型參數(shù)必須是引用數(shù)據(jù)類型,不能是基本數(shù)據(jù)類型

注:指定泛型實(shí)參時(shí),必須左右兩邊一致,不存在多態(tài)現(xiàn)象(右邊的可以省略不寫)

代碼示例:

泛型類的聲明與使用:

public class Demo1 {
? ? public static void main(String[] args) {

? ? ? ? //泛型類的使用(<T>里面只能是引用類型)
? ? ? ? Student<Double> student1 = new Student<>("學(xué)生1",99.5);
? ? ? ? Student<String> student2 = new Student<>("學(xué)生2","優(yōu)秀");
? ? ? ? Student<Character> student3 = new Student<>("學(xué)生3",'A');

?? ??? ?//輸出結(jié)果
?? ? ? ?System.out.println(student1);
? ? ? ? System.out.println(student2);
? ? ? ? System.out.println(student3);
? ? }
}

//泛型類的聲明
class Student<T> { //<T>這個(gè)就是泛型類的類型參數(shù)
? ? private String name;
? ? private T score; //使用泛型,定義分?jǐn)?shù)(分?jǐn)?shù)可能有double類型(99.5)、字符串類型(優(yōu)秀)、字符類型(‘A')等)

? ? //構(gòu)造方法
? ? public Student() {
? ? }

? ? public Student(String name, T score) {
? ? ? ? this.name = name;
? ? ? ? this.score = score;
? ? }

? ? @Override
? ? public String toString() {
? ? ? ? return "Student{" +
? ? ? ? ? ? ? ? "name='" + name + '\'' +
? ? ? ? ? ? ? ? ", score=" + score +
? ? ? ? ? ? ? ? '}';
? ? }

}

2.1泛型接口

泛型接口和泛型類關(guān)系,就像接口和類的關(guān)系一樣。 這里不多說。

語法格式:

【修飾符】 interface 接口名<類型變量列表>{
     
}

注: <類型變量列表>:可以是一個(gè)或多個(gè)類型變量,一般都是使用單個(gè)的大寫字母表示。例如:、<K,V>等。

<類型變量列表>中的類型變量不能用于靜態(tài)成員上。

2.2泛型接口的使用

使用這種類似于參數(shù)化類型的接口時(shí),我們需要注意:

指定類型變量對應(yīng)的實(shí)際類型參數(shù)
實(shí)際類型參數(shù)必須是引用數(shù)據(jù)類型,不能是基本數(shù)據(jù)類型
代碼示例

 泛型接口的聲明與使用:

public class Demo1 {
? ? public static void main(String[] args) {

? ? ? ? //泛型類的使用(<T>里面只能是引用類型)
? ? ? ? Student<Double> student1 = new Student<>("學(xué)生1",99.5);

? ? ? ? //使用泛型接口
? ? ? ? student1.print("學(xué)生1",99.5);
? ? }
}

//泛型類的聲明
class Student<T> implements Print<String,T>{ //<T>這個(gè)就是泛型類的,后面<String,T>是接口,多個(gè)類型變量
? ? private String name;
? ? private T score; //使用泛型
? ? //構(gòu)造方法
? ? public Student() {
? ? }

? ? public Student(String name, T score) {
? ? ? ? this.name = name;
? ? ? ? this.score = score;
? ? }

? ? //重寫接口的方法
? ? @Override
? ? public void print(String s, T t) {
? ? ? ? System.out.println("學(xué)生姓名:"+ this.name);
? ? ? ? System.out.println("學(xué)生成績:"+ this.score);
? ? }
}

//泛型接口的聲明
interface Print <T,V>{
? ? //定義一個(gè)打印函數(shù),可以打印學(xué)生姓名和成績
? ? public void print(T t, V v);

}

3.類型變量的上限和下限

前面說到,我們可以使用泛型類型參數(shù),這樣等我們進(jìn)行實(shí)際使用的時(shí)候,我們可以任意使用類型,但如果想只使用某一系列的類型,泛型也是可以實(shí)現(xiàn)的。這就是我們說的類型變量的上限和類型變量的下限。下面進(jìn)行分別介紹。

3.1類型變量的上限

如果泛型類定義了類型變量的上限,那么該泛型類實(shí)際的類型只能是該上限類型或者其子類類型。

語法格式:

泛型類和泛型方法的用法是一樣的,后面都不再做區(qū)分。

<類型變量  extends 上限1 & 上限2> //上限可以有多個(gè)

注:如果多個(gè)上限中有類有接口,那么只能有一個(gè)類,而且必須寫在最左邊。接口的話,可以多個(gè)。
如果在聲明<類型變量>時(shí)沒有指定上限,默認(rèn)上限是java.lang.Object。

代碼示例:

類型變量的上限:

public class Demo2 {

? ? public static void main(String[] args) {
? ? ? ? Test<Double> test1 = new Test<>(77.5); //double類
// ? ? ? ?Test<String> test2 = new Test<String>(); 不是數(shù)字類的子類
? ? ? ? Test<Integer> test3 = new Test<>(18);

? ? ? ? test1.print(77.5);
? ? ? ? test3.print(18);
? ? }
}

class Test<T extends Number >{ //數(shù)字類上限,只能使用數(shù)字類及其子類
? ? private T num;

? ? public Test() {
? ? }

? ? public Test(T num) {
? ? ? ? this.num = num;
? ? }

? ? public void print(T num){ //測試方法
? ? ? ? System.out.println(num);
? ? }
}

3.2類型變量的下限

如果泛型類定義了類型變量的下限,那么該泛型類實(shí)際的類型只能是該下限類型或者其父類類型。

語法格式:

<? ?super E > // ? 代表接收E類型或者E的父類型的元素

? 是泛型類中的通配符(下面會講到,可以先看下面的再回來看這個(gè))

代碼示例:

/*
? ? <? super 下限>
?*/

public class Demo5 {
? ? public static void main(String[] args){
? ? ? ? C<String> c=new C<>();
? ? ? ? c.setT("<? super 下限>");
? ? ? ? fun1(c);

? ? }

??? ? ?//測試函數(shù),泛型類使用了下限
? ? public static void fun1(C<? super String> c){ ?? ? //接受的數(shù)據(jù)類型只能為String、Object
? ?
? ? ? ? System.out.println(c.getT()); //輸入測試
? ? }
}

class C<T>{

? ? private T t;

? ? public T getT() {
? ? ? ? return t;
? ? }
? ? public void setT(T t) {
? ? ? ? this.t = t;
? ? }
}

4.泛型方法

鑒于某個(gè)方法定義時(shí),想要自己定義類型變量或者在某個(gè)靜態(tài)方法中定義類型變量的需求,JDK還提供了泛型方法的支持。即可以在某個(gè)方法定義時(shí),自定以<類型變量>

注:前面說到類和接口上的類型形參是不能用于靜態(tài)方法

語法格式:

【修飾符】 <類型變量列表> 返回值類型 方法名(【形參列表】)【throws 異常列表】{
    //方法體
}

注:- <類型變量列表>:可以是一個(gè)或多個(gè)類型變量,一般都是使用單個(gè)的大寫字母表示。例如: < T >、<K,V>等。
<類型變量>同樣也可以指定上限

代碼示例:

/*
? ? 泛型方法
?*/

public class Demo3 {
? ? public static void main(String[] args) {
? ? ? ? Test1 test = new Test1(); //創(chuàng)建測試對象

? ? ? ? test.print(12); //測試
? ? ? ? test.print(12.5); //測試

? ? }
}

class Test1{

? ? public <T extends Number> void print(T t){ //泛型方法,可以設(shè)置上限
? ? ? ? System.out.println("這是一個(gè)泛型方法,測試類型:" + t);
? ? }
}

5.泛型擦除

泛型擦除只是在編譯階段才會有的,在實(shí)際運(yùn)行階段類型已經(jīng)確定了,這個(gè)時(shí)候就沒有泛型的概念了(JVM并不知道泛型的存在)。這個(gè)從有泛型信息到?jīng)]有泛型信息的過程稱之為“泛型擦除”。

其擦除規(guī)則如下:

  • 若泛型類型沒有指定具體類型,用Object作為原始類型;
  • 若有限定類型< T exnteds XClass >,使用XClass作為原始類型;
  • 若有多個(gè)限定< T exnteds XClass1 & XClass2 >,使用第一個(gè)邊界類型XClass1作為原始類型;

6.類型通配符

通配符的意思是可以指代很多類型。這個(gè)主要使用在當(dāng)我們在聲明方法時(shí),不確定該泛型實(shí)際類型的情況。

類型通配符有三種:

  • <?> 任意類型
  • <? extends 上限>
  • <? super E>

下面對這三種通配符分別進(jìn)行介紹:

<?> 任意類型

當(dāng)泛型使用這種 類型通配符的時(shí)候,表示可以使用任意類型

代碼示例:

/*
? ? 類型通配符
?*/

public class Demo4 {

? ? public static void main(String[] args) {
? ? ? ? // 語文老師使用時(shí):
? ? ? ? StudentInfo<String> stu1 = new StudentInfo<String>("張三", "良好");

? ? ? ? // 數(shù)學(xué)老師使用時(shí):
? ? ? ? StudentInfo<Double> stu2 = new StudentInfo<Double>("張三", 90.5);

? ? ? ? // 英語老師使用時(shí):
? ? ? ? StudentInfo<Character> stu3 = new StudentInfo<Character>("張三", 'C');

? ? ? ? StudentInfo<?>[] arr = new StudentInfo[3]; //使用通配符
? ? ? ? arr[0] = stu1;
? ? ? ? arr[1] = stu2;
? ? ? ? arr[2] = stu3;

? ? ? ? StudentInfoPrint.print(arr); //打印輸出結(jié)果
? ? }

}


//學(xué)生類是一個(gè)參數(shù)化的泛型類
class StudentInfo<T>{
? ? private String name;
? ? private T score;

? ? public StudentInfo() {
? ? ? ? super();
? ? }
? ? public StudentInfo(String name, T score) {
? ? ? ? super();
? ? ? ? this.name = name;
? ? ? ? this.score = score;
? ? }
? ? @Override
? ? public String toString() {
? ? ? ? return "姓名:" + name + ", 成績:" + score;
? ? }
}

//學(xué)生信息打印類
class StudentInfoPrint {
? ? //泛型方法,使用通配符
? ? public static void print(StudentInfo<?>[] arr) {
? ? ? ? for (int i = 0; i < arr.length; i++) {
? ? ? ? ? ? System.out.println(arr[i]);
? ? ? ? }
? ? }
}

<? extends 上限>

? 代表接收E類型或者E的子類型的元素

代碼示例

可參考上面的類型變量的上限代碼

<? super E>

? 代表接收E類型或者E的父類型的元素

代碼示例

可參考上面的類型變量的下限代碼

到此這篇關(guān)于詳細(xì)全面解析Java泛型的文章就介紹到這了,更多相關(guān)Java泛型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • CMD運(yùn)行Intellij Idea編譯后的class文件操作

    CMD運(yùn)行Intellij Idea編譯后的class文件操作

    這篇文章主要介紹了CMD運(yùn)行Intellij Idea編譯后的class文件操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Guava輕松創(chuàng)建和管理不可變集合方法技巧

    Guava輕松創(chuàng)建和管理不可變集合方法技巧

    這篇文章主要為大家介紹了Guava輕松創(chuàng)建和管理不可變集合方法技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java關(guān)于IO流的全面介紹

    Java關(guān)于IO流的全面介紹

    下面小編就為大家?guī)硪黄狫ava關(guān)于IO流的全面介紹。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • SpringAOP中的切點(diǎn)表達(dá)式Pointcut詳解

    SpringAOP中的切點(diǎn)表達(dá)式Pointcut詳解

    這篇文章主要介紹了SpringAOP中的切點(diǎn)表達(dá)式Pointcut詳解,Spring?的?AOP?中的一個(gè)核心概念是切點(diǎn)(Pointcut),切點(diǎn)表達(dá)式定義通知(Advice)執(zhí)行的范圍,需要的朋友可以參考下
    2023-08-08
  • Java線程死鎖代碼詳解

    Java線程死鎖代碼詳解

    本篇文章主要介紹了Java線程死鎖代碼詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2021-11-11
  • SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)動態(tài)權(quán)限問題

    SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)動態(tài)權(quán)限問題

    這篇文章主要介紹了SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)-動態(tài)權(quán)限,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • MyBatis-Plus的apply用法小結(jié)

    MyBatis-Plus的apply用法小結(jié)

    apply方法是一個(gè)非常有用的功能,apply方法允許用戶直接在QueryWrapper或LambdaQueryWrapper中添加原生SQL片段,本文就詳細(xì)的介紹一下apply方法,感興趣的可以了解一下
    2024-10-10
  • Java中日期格式化YYYY-DD的操作bug

    Java中日期格式化YYYY-DD的操作bug

    這篇文章主要介紹了Java中日期格式化YYYY-DD中遇到的坑,本文給大家分享到腳本之家平臺,需要的朋友可以參考下
    2020-01-01
  • 詳解JAVA中使用FTPClient工具類上傳下載

    詳解JAVA中使用FTPClient工具類上傳下載

    這篇文章主要介紹了JAVA中使用FTPClient工具類上傳下載的相關(guān)資料,java 使用FTP服務(wù)器上傳文件、下載文件,需要的朋友可以參考下
    2017-08-08
  • Spring MVC使用視圖解析的問題解讀

    Spring MVC使用視圖解析的問題解讀

    這篇文章主要介紹了Spring MVC使用視圖解析的問題解讀,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03

最新評論

蓝田县| 安化县| 巴东县| 班玛县| 大悟县| 永定县| 万荣县| 盐亭县| 赣州市| 民勤县| 开阳县| 南召县| 揭东县| 鄂伦春自治旗| 正镶白旗| 元阳县| 侯马市| 乌拉特后旗| 玛纳斯县| 安化县| 南充市| 永仁县| 梧州市| 泾阳县| 弥勒县| 合川市| 武城县| 穆棱市| 东乡县| 临清市| 宁海县| 张家川| 思茅市| 色达县| 中江县| 无为县| 杭锦后旗| 永和县| 东兴市| 辽中县| 黎平县|