Java詳細分析講解泛型
1.泛型概念
泛型就是將類型參數(shù)化
所謂類型參數(shù)化就是將類型定義成參數(shù)的形式,然后在使用此類型的時候的時候再傳入具體的類型
到這我們可以看出來:泛型在定義的時候是不知道具體類型的,需要在使用的時候傳入具體的類型,泛型可以用在類、接口和方法中,這樣做的好處是一個泛型可以適用多種情況
2.泛型的使用
2.1泛型類語法
public class 類名<T> {......}
<T>表示這是一個泛型類,T是type的首字母大寫,除此之外的名稱還有:
E:element
K:key
V:vlaue
N:number
<>中可以有多個類型參數(shù),中間使用逗號隔開
2.2泛型方法語法
public<泛型類型> 返回值 方法名(泛型類型 參數(shù)) {......}
2.3泛型接口語法
public interface 接口名<泛型類型> {......}
2.4泛型在main方法中的使用
下面寫一個泛型類來引出后面的內(nèi)容
class Fc<T>{
private T a;
public T get (T data) {
this.a=data;
return a;
}
}前面說過泛型是在使用的時候再傳入具體的類型,所以在實例化上面泛型類的時候要指定類型。具體方式如下
類名<具體類型>變量名=new 類名<具體類型>();

注意:
- 等號右邊<>中可以不寫具體類型,編譯器可以根據(jù)上下文推導(dǎo)出此處的類型
- <>中只能寫入類,所以如果是基本數(shù)據(jù)類型,就需要寫入其對應(yīng)的包裝類,包裝類除int是Integer,char包裝類是Character外,其余均是首字母大寫
- Java中不能創(chuàng)建泛型數(shù)組,至于原因要從Java中泛型的機制說起
3.擦除機制
Java實現(xiàn)泛型是依靠這個擦除機制的,這個機制目前來講過于復(fù)雜,只說結(jié)果
Java編譯器在編譯的時候會去掉類型參數(shù),而對于泛型類型來說,如果指定上界會用上界類型進行替換,沒有指定上界則會以O(shè)bject來進行替換
所以在編譯的時候泛型類型都被替換成了Object,編譯后的class文件是不包含任何泛型信息的,即泛型信息不會進入到運行時階段
但Java的數(shù)組需要進行運行期類型檢查,而由于類型擦除,造成數(shù)組運行期類型檢查不能正常進行,破壞了Java數(shù)組運行期類型檢查的機制
4.泛型的上界
所謂泛型的上界就是對傳入的類型變量進行約束,指定哪些類型可以傳入,哪些不行,語法如下:
class 類名<類型參數(shù)extends類型邊界> {......}
還是以上面的泛型類為例,現(xiàn)在改成如下情況:
class Fc<E extends Number >{
private E a;
public E get (E data) {
this.a=data;
return a;
}
}那么此時Fc就只能傳入Number或者其子類

5.通配符
通配符就是“?”在泛型中使用,它是用來解決泛型無法協(xié)變的問題,那什么是協(xié)變?
假設(shè)有兩個類A和B,A繼承B,那么泛型Fc<A>應(yīng)該也是Fc<B>的子類,但泛型不支持這樣的父子關(guān)系
基于上面的情況,所以需要使用通配符
直接寫兩個類,A繼承B
class B {
}
class A extends B {
}

現(xiàn)在把<B>改成<?>

5.1通配符的上界
通配符也可以指定界限,語法和泛型的上界類似
<? extends 類型邊界>
假設(shè)<? extends Number>,那么可以傳入的是Number及其子類
但需要注意的是:通配符的上界只能用來讀取數(shù)據(jù),不能用來寫入數(shù)據(jù)
因為我們只知道里面可以傳入什么類型的數(shù)據(jù),但具體是什么類型我們不知道,所以也就無法對數(shù)據(jù)進行修改,但是讀取則可以直接用父類對象來進行接收讀取出來的數(shù)據(jù)
5.2通配符的下界
下界使用的是super
<? super 類型邊界>
<? super Integer>表示可以傳入Integer或者其父類
通配符下界可以進行寫入數(shù)據(jù),但不能用來讀取數(shù)據(jù)
原因也很簡單,里面可以傳的類都是Integer或者它的父類,寫進去的數(shù)據(jù)可以進行轉(zhuǎn)化,但讀取數(shù)據(jù)用哪一個父類對象接收則不好確定了
6.包裝類
由于Java中基本數(shù)據(jù)類型不是繼承Object類,所以為了泛型能夠支持基本數(shù)據(jù)類型,每一個基本數(shù)據(jù)類型都有各自的包裝類
| 基本數(shù)據(jù)類型 | 包裝類 |
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
6.1裝箱和拆箱
裝箱就是把基本數(shù)據(jù)類型改為對應(yīng)的包裝類類型,拆箱就是和裝箱相反的操作
Java中提供了自動裝箱和拆箱機制,但還是先來看下手動裝箱和拆箱的操作
//手動裝箱 int i=10; Integer j=Integer.valueOf(i); //第一種操作 Integer j=new Integer(i); //第二種操作 //手動拆箱 int a=j.intValue();
自動裝箱和拆箱的話代碼就要少的多
int i=10; Integer j=i; //自動裝箱 int a=j; //自動拆箱
關(guān)于int的包裝類有一個比較有趣的地方,裝箱使用了valueOf方法,其源碼如下:

可以看到傳給方法的參數(shù)首先是和IntegerCache進行比較,如果參數(shù)的值是在某個范圍中,那么返回的是數(shù)組里面的元素,否則返回新的對象
那我們來看看這個IntegerCache

也就是說-128<=i<=127的時候返回的是類中的數(shù)組的元素,那么就會有一個情況如下:

原因和上面所講一樣
泛型結(jié)束,后面數(shù)據(jù)結(jié)構(gòu)的時間復(fù)雜度和空間復(fù)雜度這兩個概念就不寫了,下一篇直接到順序表
到此這篇關(guān)于Java詳細分析講解泛型的文章就介紹到這了,更多相關(guān)Java泛型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于SpringBoot使用@Async的總結(jié)
這篇文章主要介紹了關(guān)于SpringBoot使用@Async的總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
使用jib插件為Java應(yīng)用構(gòu)建鏡像的方法
這篇文章主要介紹了使用jib插件為Java應(yīng)用構(gòu)建鏡像,要是用戶本地沒安裝docker,可以使用jib制作出帶有鏡像的tar文件,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-08-08
Java C++ leetcode執(zhí)行一次字符串交換能否使兩個字符串相等
這篇文章主要為大家介紹了Java C++ leetcode1790執(zhí)行一次字符串交換能否使兩個字符串相等,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
springboot整合JPA訪問Mysql的實現(xiàn)方法
本文主要介紹了springboot整合JPA訪問Mysql的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
IntelliJ IDEA里找不到j(luò)avax.servlet的jar包的解決方法
這篇文章主要介紹了IntelliJ IDEA里找不到j(luò)avax.servlet的jar包的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
使用Jenkins一鍵打包部署SpringBoot項目的步驟詳解
任何簡單操作的背后,都有一套相當(dāng)復(fù)雜的機制,本文將以SpringBoot應(yīng)用的在Docker環(huán)境下的打包部署為例,詳細講解如何使用Jenkins一鍵打包部署SpringBoot應(yīng)用,文中通過圖文結(jié)合講解的非常詳細,需要的朋友可以參考下2023-11-11

