关于Java泛型和擦除
“編譯期間擦除泛型”是常識(shí)(好吧,類型參數(shù)和實(shí)參實(shí)際上就是被擦除的)。 這是由于“類型擦除”而發(fā)生的。 但這是錯(cuò)誤的,正如許多開發(fā)人員所假設(shè)的那樣,刪除了<..>符號(hào)內(nèi)指定的所有內(nèi)容。 請參見下面的代碼:
你知道那是什么嗎?
類java.lang.String
類ClassTest $ Bar
類java.lang.String
類java.lang.StringBuilder
接口java.lang.CharSequence
您會(huì)看到每個(gè)類型的參數(shù)都會(huì)保留下來,并且可以在運(yùn)行時(shí)通過反射進(jìn)行訪問。 但是,什么是“類型擦除”? 必須刪除某些內(nèi)容嗎? 是。 實(shí)際上,除結(jié)構(gòu)化結(jié)構(gòu)外,其他所有結(jié)構(gòu)均與之相關(guān)–上面的所有內(nèi)容都與類的結(jié)構(gòu)有關(guān),而不是與程序流程有關(guān)。 換句話說,有關(guān)類的類型參數(shù)及其字段和方法的元數(shù)據(jù)被保留以通過反射進(jìn)行訪問。
但是,其余部分將被刪除。 例如,以下代碼:
List<String> list = new ArrayList<>(); Iterator<String> it = list.iterator(); while (it.hasNext()) {String s = it.next(); }實(shí)際上將被轉(zhuǎn)換為此(兩個(gè)片段的字節(jié)碼相同):
List list = new ArrayList(); Iterator it = list.iterator(); while (it.hasNext()) {String s = (String) it.next(); }因此,將刪除您在方法主體中定義的所有類型參數(shù),并在需要的地方添加強(qiáng)制類型轉(zhuǎn)換。 另外,如果定義了一個(gè)方法以接受List<T> ,則此T將被轉(zhuǎn)換為Object(或如果聲明了其邊界,則轉(zhuǎn)換為其界限。這就是為什么您不能執(zhí)行new T() (順便說一句,有關(guān)此擦除的公開問題 )。
到目前為止,我們已經(jīng)涵蓋了類型擦除定義的前兩點(diǎn)。 第三個(gè)是關(guān)于橋接方法。 我已經(jīng)用這個(gè)stackoverflow問題(和答案)進(jìn)行了說明 。
所有這兩個(gè)“道德”。 首先,java泛型很復(fù)雜。 但是您可以在不了解所有復(fù)雜性的情況下使用它們。
其次,不要假設(shè)所有類型信息都被刪除了–結(jié)構(gòu)類型參數(shù)在那里,因此,如果需要,可以使用它們(但不要過分依賴反射)。
翻譯自: https://www.javacodegeeks.com/2014/11/on-java-generics-and-erasure.html
總結(jié)
以上是生活随笔為你收集整理的关于Java泛型和擦除的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PrimeFaces 5.0 DataT
- 下一篇: 如何在Java中将图像上传到DropBo