Java?泛型考古?泛型擦除?包裝類詳細(xì)解析
一. 什么是泛型
泛型(generic type)其本質(zhì)是將類型參數(shù)化,也就是說(shuō)所操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù)這種參數(shù)類型可以用在類、接口和方法的創(chuàng)建中,分別稱為泛型類、泛型接口、泛型方法。
二. 為什么要有泛型 ?
之前寫(xiě)過(guò)MyArrayList順序表,這個(gè)類當(dāng)時(shí)自己在實(shí)現(xiàn)的時(shí)候只能用一種類型來(lái)表示,也就是用的時(shí)候自己實(shí)現(xiàn)的MyArrayList只能應(yīng)用于一種類型,要想應(yīng)用于其他類型,就得再寫(xiě)一個(gè)其他類型的MyArrayList,這樣就比較麻煩,而有了泛型之后就很好的解決了這個(gè)問(wèn)題,讓類型參數(shù)化,使得自己寫(xiě)的MyArrayList可以適用于多種場(chǎng)景
通過(guò)以下代碼對(duì)比就可發(fā)現(xiàn)泛型的方便之處
示例
不帶泛型
public class MyArrayList { private int[] array; private int size; // 有效數(shù)據(jù)個(gè)數(shù) public MyArrayList() { this.array = new int[10]; this.size = 0; } public void add(int x) { // 暫不考慮擴(kuò)容 this.array[size] = x; this.size++; } }
帶泛型
import org.omg.CORBA.Object; public class MyArrayList2<E> { // 在類的實(shí)現(xiàn)中,可以直接將類當(dāng)成一種數(shù)據(jù)類型來(lái)使用。在實(shí)例化該類的時(shí)候這個(gè)類型才被確定 private E[] array; private int size; // 有效數(shù)據(jù)個(gè)數(shù) public MyArrayList2() { this.array = (E[])new Object[10]; // 注意:Java中泛型不允許定義數(shù)組 this.size = 0; } public void add(E e) { // 不考慮擴(kuò)容 this.array[size] = e; this.size++; } } // 帶泛型的順序表元素類型是一個(gè)“變量” // E就是變量的名稱
通過(guò)上面這兩段代碼的對(duì)比,就可以發(fā)現(xiàn),帶泛型的順序表和不帶泛型的順序表只是表示類型的部分不一樣,代碼所實(shí)現(xiàn)的邏輯是一樣的
類的實(shí)例化與使用
public static void main(String[] args) { MyArrayList myArrayList = new MyArrayList(); myArrayList.add(1); myArrayList.add(2); // 這里其實(shí)就相當(dāng)于是將String類型賦值給E MyArrayList2<String> stringMyArrayList2 = new MyArrayList2<String>(); // 等號(hào)右邊的<>內(nèi)可以省略 stringMyArrayList2.add("1"); // 要想用基本類型,要寫(xiě)基本類型對(duì)應(yīng)的包裝類 stringMyArrayList2.add("2"); }
對(duì)于泛型來(lái)說(shuō),類型是在使用該類時(shí)才明確定義出來(lái)的
三、泛型考古
要知道其實(shí)剛開(kāi)始Java體系中是沒(méi)有泛型的,是在JDK1.5之后才才有了泛型
在JDK1.5之前是利用Object引用可以指向任意類型的對(duì)象實(shí)現(xiàn)類似泛型的效果
- Object類是所有類的祖先類
- 上層引用可以指向下層對(duì)象
如下代碼:
public class MyArrayList3 { private Object[] array; private int size; public MyArrayList3() { this.array = new Object[10]; this.size = 0; } public void add(Object e) { this.array[size] = e; size++; } }
這種做法的缺點(diǎn)也很明顯,就是new了一個(gè)MyArrayList,里面打算存int類型的數(shù)據(jù),但由于手滑,存入了一個(gè)String類型的數(shù)據(jù),這樣的話編譯器是不會(huì)報(bào)錯(cuò)的,程序也能正常運(yùn)行,直到需要取list中的元素的時(shí)候程序才會(huì)拋出異常。
泛型就很好的解決了這個(gè)問(wèn)題,只要類型不匹配,錯(cuò)誤會(huì)在第一時(shí)間暴露出來(lái)
四、泛型擦除
雖然在 JDK1.5 之后有了泛型,但其實(shí)JDK的底層實(shí)現(xiàn)還是用的上面Object來(lái)實(shí)現(xiàn)的
如下圖
我們雖然用的是泛型,但其實(shí)泛型只存在于編譯階段,在編譯過(guò)程中也伴隨著泛型擦除,在生成.class
文件的時(shí)候泛型信息就已經(jīng)不存在了,成了JDK1.5之前的Object方式
查看MyArrayList的字節(jié)碼文件就可以看出來(lái)
所以Java的泛型只存在于編譯階段(Java核心原理:Object引用可以指向任意類型的對(duì)象)
五、包裝類
由于8種基本類型不是類
類型,Java專門(mén)為它們定義了各自的包裝類
如下:
byte java.lang.Byte
short java.lang.Short
char java.lang.Character
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double
boolean java.lang.Boolean
六、裝箱拆箱
Java中提供了便利,如果沒(méi)有歧義,Java 會(huì)幫我們自動(dòng)裝箱,自動(dòng)拆箱
Integer a = 10; // 把int賦值給Integer類型,隱含著發(fā)生了裝箱過(guò)程 int b = a; // 把Integer賦值給int類型,隱含著發(fā)生了拆箱過(guò)程
隱式裝箱和拆箱過(guò)程只存在于編譯階段,編譯完成就變成顯式裝箱,顯式拆箱了
到此這篇關(guān)于Java 泛型考古 泛型擦除 包裝類詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java 泛型 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解SpringBoot如何實(shí)現(xiàn)多環(huán)境配置
在實(shí)際的軟件開(kāi)發(fā)過(guò)程中,一個(gè)應(yīng)用程序通常會(huì)有多個(gè)環(huán)境,pring?Boot?提供了一個(gè)非常靈活和強(qiáng)大的方式來(lái)管理這些環(huán)境配置,下面就跟隨小編一起學(xué)習(xí)一下吧2023-07-07Java如何實(shí)現(xiàn)壓縮文件與解壓縮zip文件
這篇文章主要介紹了Java如何實(shí)現(xiàn)壓縮文件與解壓縮zip文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12java實(shí)現(xiàn)系統(tǒng)多級(jí)文件夾復(fù)制
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)系統(tǒng)多級(jí)文件夾復(fù)制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08編碼實(shí)現(xiàn)從無(wú)序鏈表中移除重復(fù)項(xiàng)(C和JAVA實(shí)例)
如果不能使用臨時(shí)緩存,你怎么實(shí)現(xiàn)無(wú)序鏈表中移除重復(fù)項(xiàng)(?C和JAVA實(shí)例無(wú)序鏈表中移除重復(fù)項(xiàng)。2013-10-10