溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

發(fā)布時(shí)間:2021-09-15 10:50:27 來(lái)源:億速云 閱讀:132 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

泛型與類(lèi)型擦除

泛型,JDK 1.5新特性,本質(zhì)是參數(shù)化類(lèi)型(Parametersized Type) 的應(yīng)用,即所操作的數(shù)據(jù)類(lèi)型被指定為一個(gè)參數(shù)。這種參數(shù)類(lèi)型可用在:

  • 類(lèi)

  • 接口

  • 方法

的創(chuàng)建中, 分別稱(chēng)為:

  • 泛型類(lèi)

  • 泛型接口

  • 泛型方法

在Java還沒(méi)有泛型的版本時(shí)。只能通過(guò):

  1. Object 是所有類(lèi)型的父類(lèi)

  2. 類(lèi)型強(qiáng)制轉(zhuǎn)換

兩個(gè)特性協(xié)作實(shí)現(xiàn)類(lèi)型泛化。例如,在哈希表的存取中,JDK 1.5之前使用HashMap的get() 方法,返回值就是個(gè)Object。由于Java語(yǔ)言里面所有的類(lèi)型都維承于java.lang.Object,所以O(shè)bject轉(zhuǎn)型成任何對(duì)象都有可能。但也因?yàn)橛袩o(wú)限的可能性,就只有程序員和運(yùn)行期的虛擬機(jī)才知道這個(gè)Objet到底是個(gè)什么類(lèi)型的對(duì)象。
編譯期間,編譯器無(wú)法檢查該Object的強(qiáng)制轉(zhuǎn)型是否成功。若僅僅依賴(lài)程序員去保障正確性,許多ClassCastException的風(fēng)險(xiǎn)就會(huì)延遲到程序運(yùn)行期。

Java語(yǔ)言中的泛型則不一樣,它只在程序源碼中存在,在編譯后的字節(jié)碼文件中,就已經(jīng)替換為原來(lái)的原生類(lèi)型(Raw Type) ,并在相應(yīng)地方插入強(qiáng)制轉(zhuǎn)換代碼。
因此,對(duì)運(yùn)行期的Java來(lái)說(shuō)Araylist<int>、Aralist<String>是同一個(gè)類(lèi)。所以泛型是Java語(yǔ)言的一顆語(yǔ)法糖Java稱(chēng)為類(lèi)型擦除,基于這種方法實(shí)現(xiàn)的泛型稱(chēng)為偽泛型。

  • 泛型擦除前的例子

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

把這段Java代碼編譯成Class文件,然后再用字節(jié)碼反編譯后,將會(huì)發(fā)現(xiàn)泛型都不見(jiàn)了,又變回了Java泛型出現(xiàn)之前的寫(xiě)法,泛型類(lèi)型都變回了原類(lèi)型。如:

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

通過(guò)擦除實(shí)現(xiàn)泛型,喪失了一些泛型思想應(yīng)有的優(yōu)雅

  • 當(dāng)泛型遇見(jiàn)重載1

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

不能被編譯的,因?yàn)閰?shù)List<Integer>List<String>編譯之后都被擦除了。變成了一樣的原生類(lèi)型List<E>,擦除動(dòng)作導(dǎo)致這兩種方法的特征簽名變得一模一樣。初步看來(lái),無(wú)法重載的原因已經(jīng)找到了,但真的就如此嗎? 只能說(shuō),泛型擦除成相同的原生類(lèi)型只是無(wú)法重載的部分原因當(dāng)

  • 泛型遇見(jiàn)置載2

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

由于Java泛型的引入,各種場(chǎng)景(虛擬機(jī)解析、反射等)下的方法調(diào)用都可能對(duì)原有基礎(chǔ)產(chǎn)生影響,如在泛型類(lèi)中如何獲取傳入的參數(shù)化類(lèi)型等。因此,JCP組織對(duì)虛擬機(jī)規(guī)范做出了相應(yīng)的修改,引入了諸如Signature、LocalVariableTypeTable 等新的屬性用于解決伴隨泛型而來(lái)的參數(shù)類(lèi)型的識(shí)別問(wèn)題,Signature 是其中最重要的一項(xiàng)屬性,它的作用就是存儲(chǔ)一個(gè)方法在字節(jié)碼層面的特征簽名,這個(gè)屬性中保存的參數(shù)類(lèi)型并不是原生類(lèi)型,而是包括了參數(shù)化類(lèi)型的信息。修改后的虛擬機(jī)規(guī)范要求所有能識(shí)別49.0以上版本的Class文件的虛擬機(jī)都要能正確地識(shí)別Signature參數(shù)。

從Signature屬性的出現(xiàn)我們還可以得出結(jié)論,所謂的擦除,僅僅是對(duì)方法的Code屬性中的字節(jié)碼進(jìn)行擦除,實(shí)際上元數(shù)據(jù)還是保留了泛型信息,這也是我們能通過(guò)反射取得參數(shù)化類(lèi)型的根本依據(jù)。

  • 自動(dòng)裝箱: 拆箱與遍歷循環(huán)

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

  • 自動(dòng)裝箱: 拆箱與遍歷循環(huán)編譯后

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

遍歷循環(huán)則把代碼還原成了迭代器的實(shí)現(xiàn),這也是為何遍歷循環(huán)需要被遍歷的類(lèi)實(shí)現(xiàn)Iterable接口的原因。最后再看看變長(zhǎng)參數(shù),它在調(diào)用的時(shí)候變成了一個(gè)數(shù)組類(lèi)型的參數(shù),在變長(zhǎng)參數(shù)出現(xiàn)之前,程序員就是使用數(shù)組來(lái)完成類(lèi)似功能的。

Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析

以上是“Java語(yǔ)法中泛型與類(lèi)型擦除的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI