日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

詳解Java 中泛型的實(shí)現(xiàn)原理

瀏覽:87日期:2022-08-15 17:25:24

泛型是 Java 開發(fā)中常用的技術(shù),了解泛型的幾種形式和實(shí)現(xiàn)泛型的基本原理,有助于寫出更優(yōu)質(zhì)的代碼。本文總結(jié)了 Java 泛型的三種形式以及泛型實(shí)現(xiàn)原理。

泛型

泛型的本質(zhì)是對(duì)類型進(jìn)行參數(shù)化,在代碼邏輯不關(guān)注具體的數(shù)據(jù)類型時(shí)使用。例如:實(shí)現(xiàn)一個(gè)通用的排序算法,此時(shí)關(guān)注的是算法本身,而非排序的對(duì)象的類型。

泛型方法

如下定義了一個(gè)泛型方法, 聲明了一個(gè)類型變量,它可以應(yīng)用于參數(shù),返回值,和方法內(nèi)的代碼邏輯。

class GenericMethod{ public <T> T[] sort(T[] elements){ return elements; }}泛型類

與泛型方法類似,泛型類也需要聲明類型變量,只不過位置放在了類名后面,作用的范圍包括了當(dāng)前中的成員變量類型,方法參數(shù)類型,方法返回類型,以及方法內(nèi)的代碼中。

子類繼承泛型類時(shí)或者實(shí)例化泛型類的對(duì)象時(shí),需要指定具體的參數(shù)類型或者聲明一個(gè)參數(shù)變量。如下,SubGenericClass 繼承了泛型類 GenericClass,其中類型變量 ID 的值為 Integer,同時(shí)子類聲明了另一個(gè)類型變量 E,并將E 填入了父類聲明的 T 中。

class GenericClass<ID, T>{ }class SubGenericClass<T> extends GenericClass<Integer, T>{ }泛型接口

泛型接口與泛型類類似,也需要在接口名后面聲明類型變量,作用于接口中的抽象方法返回類型和參數(shù)類型。子類在實(shí)現(xiàn)泛型接口時(shí)需要填入具體的數(shù)據(jù)類型或者填入子類聲明的類型變量。

interface GenericInterface<T> { T append(T seg);}泛型的基本原理

泛型本質(zhì)是將數(shù)據(jù)類型參數(shù)化,它通過擦除的方式來實(shí)現(xiàn)。聲明了泛型的 .java 源代碼,在編譯生成 .class 文件之后,泛型相關(guān)的信息就消失了。可以認(rèn)為,源代碼中泛型相關(guān)的信息,就是提供給編譯器用的。泛型信息對(duì) Java 編譯器可以見,對(duì) Java 虛擬機(jī)不可見。

Java 編譯器通過如下方式實(shí)現(xiàn)擦除:

用 Object 或者界定類型替代泛型,產(chǎn)生的字節(jié)碼中只包含了原始的類,接口和方法; 在恰當(dāng)?shù)奈恢貌迦霃?qiáng)制轉(zhuǎn)換代碼來確保類型安全; 在繼承了泛型類或接口的類中插入橋接方法來保留多態(tài)性。

Java 官方文檔原文

Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.Insert type casts if necessary to preserve type safety.Generate bridge methods to preserve polymorphism in extended generic types.

下面通過具體代碼來說明 Java 中的類型擦除。

實(shí)驗(yàn)原理:先用 javac 將 .java 文件編譯成 .class 文件,再使用反編譯工具 jad 將 .class 文件反編成回 Java 代碼,反編譯出來的 Java 代碼內(nèi)容反映的即為 .class 文件中的信息。

如下源代碼,定義 User 類,實(shí)現(xiàn)了 Comparable 接口,類型參數(shù)填入 User,實(shí)現(xiàn) compareTo 方法。

class User implements Comparable<User> { String name; public int compareTo(User other){ return this.name.compareTo(other.name); }}

JDK 中 Comparable 接口源碼內(nèi)容如下:

package java.lang;public interface Comparable<T>{ int compareTo(T o);}

我們首先反編譯它的接口,Comparable 接口的字節(jié)碼文件,可以在 $JRE_HOME/lib/rt.jar 中找到,將它復(fù)制到某個(gè)目錄。使用 jad.exe(需要另外安裝)反編譯這個(gè) Comparable.class 文件。

$ jad Comparable.class

反編譯出來的內(nèi)容放在 Comparable.jad 文件中,文件內(nèi)容如下:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://www.kpdus.com/jad.html// Decompiler options: packimports(3)// Source File Name: Comparable.javapackage java.lang;// Referenced classes of package java.lang:// Objectpublic interface Comparable{ public abstract int compareTo(Object obj);}

對(duì)比源代碼 Comparable.java 和反編譯代碼 Comparable.jad 的內(nèi)容不難發(fā)現(xiàn),反編譯之后的內(nèi)容中已經(jīng)沒有了類型變量 T 。compareTo 方法中的參數(shù)類型 T 也被替換成了 Object。這就符合上面提到的第 1 條擦除原則。這里演示的是用 Object 替換類型參數(shù),使用界定類型替換類型參數(shù)的例子可以反編譯一下 Collections.class 試試,里面使用了大量的泛型。

使用 javac.exe 將 User.java 編譯成 .class 文件,然后使用 jad 將 .class 文件反編譯成 Java 代碼。

$ javac User.java$ jad User.class

User.jad 文件內(nèi)容如下:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://www.kpdus.com/jad.html// Decompiler options: packimports(3)// Source File Name: User.javaclass User implements Comparable{ User() { } public int compareTo(User user) { return name.compareTo(user.name); } // 橋接方法 public volatile int compareTo(Object obj) { return compareTo((User)obj); } String name;}

對(duì)比編輯的源代碼 User.java 和反編譯出來的代碼 User.jad,容易發(fā)現(xiàn):類型參數(shù)沒有了,多了一個(gè)無參構(gòu)造方法,多了一個(gè) compareTo(Object obj) 方法,這個(gè)就是橋接方法,還可以發(fā)現(xiàn)參數(shù) obj 被強(qiáng)轉(zhuǎn)成 User 再傳入 compareTo(User user) 方法。通過這些內(nèi)容可以看到擦除規(guī)則 2 和規(guī)則 3 的實(shí)現(xiàn)方式。

強(qiáng)轉(zhuǎn)規(guī)則比較好理解,因?yàn)榉盒捅惶鎿Q成了 Object,要調(diào)用具體類型的方法或者成員變量,當(dāng)然需要先強(qiáng)轉(zhuǎn)成具體類型才能使用。那么插入的橋接方法該如何理解呢?

如果我們只按照下面方式去使用 User 類,這樣確實(shí)不需要參數(shù)類型為 Object 的橋接方法。

User user = new User();User other = new User();user.comparetTo(other);

但是,Java 中的多態(tài)特性允許我們使用一個(gè)父類或者接口的引用指向一個(gè)子類對(duì)象。

Comparable<User> user = new User();

而按照 Object 替換泛型參數(shù)原則,Comparable 接口中只有 compareTo(Object) 方法,假設(shè)沒有橋接方法,顯然如下代碼是不能運(yùn)行的。所以 Java 編譯器需要為子類(泛型類的子類或泛型接口的實(shí)現(xiàn)類)中使用了泛型的方法額外生成一個(gè)橋接方法,通過這個(gè)方法來保證 Java 中的多態(tài)特性。

Comparable<User> user = new User();Object other = new User();user.compareTo(other);

而普通類中的泛型方法在進(jìn)行類型擦除時(shí)不會(huì)產(chǎn)生橋接方法。例如:

class Dog{ <T> void eat(T[] food){ }}

類型擦除之后變成了:

class Dog{ Dog() { } void eat(Object aobj[]) { }}小結(jié)

Java 中的泛型有 3 種形式,泛型方法,泛型類,泛型接口。Java 通過在編譯時(shí)類型擦除的方式來實(shí)現(xiàn)泛型。擦除時(shí)使用 Object 或者界定類型替代泛型,同時(shí)在要調(diào)用具體類型方法或者成員變量的時(shí)候插入強(qiáng)轉(zhuǎn)代碼,為了保證多態(tài)特性,Java 編譯器還會(huì)為泛型類的子類生成橋接方法。類型信息在編譯階段被擦除之后,程序在運(yùn)行期間無法獲取類型參數(shù)所對(duì)應(yīng)的具體類型。

參考

https://docs.oracle.com/javase/tutorial/java/generics/index.html

https://stackoverflow.com/questions/25040837/generics-bridge-method-on-polymorphism

以上就是詳解Java 中泛型的實(shí)現(xiàn)原理的詳細(xì)內(nèi)容,更多關(guān)于Java 泛型實(shí)現(xiàn)原理的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品日韩久久久| 日韩视频二区| 国产探花一区| 国产欧美精品久久| 精品丝袜久久| 另类专区亚洲| 日韩精品电影| 精品国模一区二区三区| 91精品国产91久久久久久黑人| 日韩在线免费| 99xxxx成人网| 国产美女久久| 日韩欧美一区二区三区免费观看| 亚洲韩日在线| 日韩三区四区| 97精品国产| 久久国产成人| 欧美激情三区| 午夜国产欧美理论在线播放| 日本电影久久久| 国产一区二区三区91| 免费在线小视频| 巨乳诱惑日韩免费av| 欧美欧美黄在线二区| 日韩深夜视频| 视频一区视频二区中文字幕| 国产精品v亚洲精品v日韩精品 | 久久国产毛片| 亚洲精选av| 成人国产精品| 视频一区中文字幕| 国产成人免费av一区二区午夜| 99精品视频在线| 亚洲精品影院在线观看| 精品久久亚洲| 在线亚洲激情| 久草精品视频| 中文视频一区| 性感美女一区二区在线观看| 日韩高清在线不卡| 视频二区不卡| 国产精品久久777777毛茸茸| 欧美午夜不卡| 成人国产精品一区二区免费麻豆| 鲁大师成人一区二区三区| 精品72久久久久中文字幕| 中文字幕av一区二区三区人| 午夜av成人| 国产精品一区二区精品视频观看| 欧美/亚洲一区| 国产麻豆一区| 美女久久一区| 久久久久美女| 国内精品亚洲| 欧美日一区二区在线观看| 亚洲一区不卡| 亚洲午夜精品久久久久久app| 国产精品日本一区二区不卡视频 | caoporn视频在线| 亚欧成人精品| 日韩在线观看一区| 欧美精品中文| 日韩精品一卡二卡三卡四卡无卡 | 欧美日韩国产观看视频| 久久国际精品| 免费在线观看成人| 激情欧美一区二区三区| 三级在线看中文字幕完整版| 美女在线视频一区| 国产三级一区| 热久久久久久| 日本va欧美va精品| 亚洲狼人精品一区二区三区| 91国语精品自产拍| a国产在线视频| 久久wwww| 国产欧美精品久久| 日韩精品久久久久久久软件91| 99热精品在线| 1000部精品久久久久久久久| 在线人成日本视频| 手机在线电影一区| 日产精品一区二区| 精品国产亚洲日本| 久久精品国产成人一区二区三区| 日韩精品91亚洲二区在线观看| 久久国产精品久久久久久电车 | 婷婷国产精品| 国产在线|日韩| 日韩免费福利视频| av资源中文在线| 吉吉日韩欧美| 亚洲韩日在线| 美女国产一区| 日本a级不卡| 国产精品国码视频| 欧美成人一二区| 精品国产一区二区三区av片| 久久一区精品| 视频在线不卡免费观看| 中文字幕人成乱码在线观看| 天堂av在线| 日韩精品免费一区二区在线观看| 国产福利片在线观看| 亚洲天堂资源| 国产99精品一区| 亚洲一级高清| 男人操女人的视频在线观看欧美| 国产精品三上| 日本不卡不码高清免费观看 | 欧美一级二级三级视频| 国产精品视频一区二区三区 | 黄色在线网站噜噜噜| 欧洲av不卡| 亚洲国产专区校园欧美| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲免费福利一区| 国产美女视频一区二区| 精品美女在线视频| 亚洲无线一线二线三线区别av| 国产亚洲亚洲| 亚洲毛片在线免费| 国产精品videosex极品| 成人污污视频| 日韩视频一区二区三区在线播放免费观看| 激情丁香综合| 中文在线日韩| 精品国产欧美日韩| 日韩网站在线| 欧美精品91| 美女毛片一区二区三区四区 | 99视频精品全部免费在线视频| 亚洲作爱视频| 91福利精品在线观看| 久久久久久一区二区| 亚洲一区国产| 国产精品久久国产愉拍| 国产一区清纯| 亚洲精品黄色| 精品视频免费| 亚洲免费黄色| 久久免费精品| 亚洲在线观看| 久久精品国产在热久久| 老司机精品久久| 国产96在线亚洲| 一区二区不卡| 色在线视频观看| 日韩高清在线观看一区二区| 欧美日韩视频网站| 日韩av影院| 私拍精品福利视频在线一区| 四虎成人精品一区二区免费网站| 精品精品国产三级a∨在线| 国产精品美女| sm捆绑调教国产免费网站在线观看 | 日韩一区二区三区免费视频| 国产成人免费| 亚洲精品进入| 精品日韩视频| 欧美精品导航| 久久亚洲电影| 日韩av免费| 国产精品xxx在线观看| 香蕉精品久久| 四虎国产精品免费观看| 88久久精品| 免费观看久久久4p| 亚洲第一区色| 91日韩免费| 欧美国产日本| 日本三级亚洲精品| 国产亚洲永久域名| 日韩大片在线观看| 国产精品草草| 日韩黄色av| 亚洲一区国产| 欧美日韩一二三四| 国产66精品| 日本aⅴ免费视频一区二区三区| 日韩一级欧洲| 激情婷婷综合| 男人操女人的视频在线观看欧美| 亚洲一级特黄| 日韩精品欧美| 色黄视频在线观看| 久久精品一区二区国产| 亚洲免费福利一区| 丝袜美腿高跟呻吟高潮一区| 欧美一区二区三区激情视频| 国产福利片在线观看| 久久久久黄色| 麻豆国产欧美一区二区三区| 久久国内精品自在自线400部| 香蕉精品视频在线观看| www成人在线视频| 日韩免费视频| 中文一区一区三区高中清不卡免费| 久久影院资源站| 精品久久一区|