版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Java泛型type體系整理一直對(duì)jdk的ref使用比較模糊,早上花了點(diǎn)時(shí)間簡(jiǎn)單的整理了下,也幫助自己理解一下泛型的一些處理。java中class,method,field的繼承體系java中所有對(duì)象的類(lèi)型定義類(lèi)Type<<interTace>>Type<<interface><<interTace>>Type<<interface>>GenericArrayType<<interface>>ParameterizedType<<inteType\十:void*ge^BoundsO-hg^GenericD-hg^NameO:十qeJAcfuaJTen^s0:void-hge?RawTv?9e(?:void-hge^OwnerT^eO:void說(shuō)明:Type:TypeisthecommonsuperinterfaceforalltypesintheJavaprogramminglanguage.Theseincluderawtypes,parameterizedtypes,arraytypes,typevariablesandprimitivetypes.使用一般我們不直接操作Type類(lèi)型,所以第一次使用會(huì)對(duì)這個(gè)比較陌生,相對(duì)內(nèi)部的一些概念。根據(jù)Type類(lèi)型分類(lèi),整理了一個(gè)type->class的轉(zhuǎn)換過(guò)程,同理也包括處理GenericType。支持多級(jí)泛型處理。Java代碼1privatestaticClassgetClass(Typetype,inti)(if(typeinstanceofParameterizedType){//處
理泛型類(lèi)型returngetGenericClass((Param理泛型類(lèi)型TOC\o"1-5"\h\zeterizedType)type,i);4stanceofTypeVariable){5}elseif(typeinreturn}elseif(typeinreturn(Class)getClass(((TypeVariable)理泛型擦拭對(duì)象6}else{//class本身也是type,強(qiáng)制轉(zhuǎn)型7return(Class)type;8}9}1011privatestaticClassgetGenericClass(ParameterizedTypeparameterizedType,inti){12ObjectgenericClass=parameterizedType.getActualTypeArguments()[i];13if(genericClassinstanceofParameterizedType){//處理多級(jí)泛型14return(Class)((ParameterizedType)genericClass).getRawType();15}elseif(genericClassinstanceofGenericArrayType){//處理數(shù)組泛型16return(Class)((GenericArrayType)genericClass).getGenericComponentType();17}elseif(genericClassinstanceofTypeVariable){//處理泛型擦拭對(duì)象18return(Class)getClass(((TypeVariable)genericClass).getBounds()[0],0);19}else{20return(Class)genericClass;2}22}23測(cè)試代碼:Java代碼1interfaceGeneircInteface{23Tmethod1(Tobj);4}56interfaceCommonInteface{78Integermethod2(Integerobj);9}1011classBaseGeneircIntefaceimplementsGeneircInteface{1213protectedRresult;1415@Override16publicRmethod1(Robj){17returnobj;18}1920}2122classGenericClassextendsBaseGeneircInteface<list>implementsGeneircInteface<list>,CommonInteface{2324@Override25publicListmethod1(Listobj){26result=obj.;27returnresult;28}2930publicIntegermethod2(Integerobj){31returnobj;32}3334public<t,e<span="">extendsThrowable>Tmethod3(Tobj)throwsE{35returnobj;36}3738}針對(duì)class的泛型接口使用:Java代碼privatestaticvoidclassGeneric(){System.out.println("\nclassGeneric");GenericClassgc=newGenericClass();Type[]gis=gc.getClass().getGenericInterfaces();//接口的泛型信息Typegps=gc.getClass().getGenericSuperclass();//父類(lèi)的泛型信息TypeVariable[]gtr=gc.getClass().getTypeParameters();//當(dāng)前接口的參數(shù)信息System.out.println("==============getGenericInterfaces");for(Typet:gis)(System.out.println(t+":"+getClass(t,0));}System.out.println("==============getGenericSuperclass");System.out.println(getClass(gps,0));System.out.println("==============getTypeParameters");for(TypeVariablet:gtr){StringBuilderstb=newStringBuilder();for(Typetp:t.getBounds()){stb.append(tp+":");}System.out.println(t+":"+t.getName()++stb);}針對(duì)method的泛型接口使用:Java代碼1privatestaticvoidmethodGeneric()throwsException{2System.out.println("\nmethodGeneric");3GenericClassgc=newGenericClass();4Methodmethod3=gc.getClass().getDeclaredMethod("method3”,newClass[]{Object.class});56Type[]gpt3=method3.getGenericParameterTypes();7Type[]get3=method3.getGenericExceptionTypes();8Typegt3=method3.getGenericReturnType();9System.out.println("==============getGenericParameterTypes");10for(Typet:gpt3){11System.out.println(t+":"+getClass
(t,0));12}13System.out.println("==============getGenericExceptionTypes");14for(Typet:get3){15System.out.println(t+":"+getClass(t,0));16}17System.out.println("==============getType");18System.out.println(gt3+":"+getClass(gt3,0));19}20針對(duì)field的泛型接口使用:Java代碼1privatestaticvoidfieldGeneric()throwsException{System.out.println("\n-fieldGeneric");3GenericClassgc=newGenericClass();4Fieldfield=gc.getClass().getSuperclass().getDeclaredField("result");56Typegt=field.getGenericType();7Typeft=field.getType();8System.out.println("==============getGenericType);9System.out.println(gt+":"+getClass(gt,0));10System.out.println("==============getType");11System.out.println(ft+""+getClass(ft,0));12}
輸出結(jié)果:Java代碼1classGeneric--2==============getGenericInterfaces3com.agapple.misc.GeneircInteface<java.util.list>:interfacejava.util.List4interfacecom.agapple.misc.CommonInteface:interfacecom.agapple.misc.CommonInteface5==============getGenericSuperclass6interfacejava.util.List7==============getTypeParameters89fieldGeneric10==============getGenericType11R:classjava.lang.Object12==============getType13classjava.lang.Object:classjava.lang.Object1415methodGeneric16==============getGenericParameterTypes17T:classjava.lang.Object18==============getGenericExceptionTypes19E:classjava.lang.Throwable20==============getType21T:classjava.lang.Object22結(jié)果說(shuō)明:
因?yàn)榉盒偷牟潦茫瑢?duì)應(yīng)的GeneircInteface和BaseGeneircInteface,在源碼信息已被擦除對(duì)應(yīng)的類(lèi)型,進(jìn)行了upper轉(zhuǎn)型,所以取到的是Object??梢允褂胑xtendsGenericClass在類(lèi)定義時(shí),聲明了繼承父接口的泛型為L(zhǎng)ist,所以再通過(guò)接口和父類(lèi)獲取泛型信息時(shí),是能正確的獲取。通過(guò)javap-v可以獲取對(duì)應(yīng)的class信息Java代碼const#46=AscizLcom/agapple/misc/BaseGeneircInteface;>;Lcom/agapple/misc/GeneircInteface;>;Lcom/agapple/misc/CommonInteface;;而在GenericClass中定義的方法methods,在class信息是一個(gè)被向上轉(zhuǎn)型后擦拭的信息。所以獲取methods的相關(guān)泛型信息是沒(méi)有的。Java代碼1method3;2const#36=Asciz(Ljava/lang/Object;)Ljava/lang/Object;;3const#37=AscizExceptions;
4const#38=class#39;//java/lang/Throwable5const#39=Ascizjava/lang/Throwable;6const#40=Asciz(TT;)TT;ATE;;7const#41=AscizTT;;8思考問(wèn)題:Listlist=newArragList();是否有獲取對(duì)應(yīng)的String泛型信息?不能,臨時(shí)變量不能保存泛型信息到具體class對(duì)象中,List和List對(duì)應(yīng)的class實(shí)體是同一個(gè)。Java代碼TOC\o"1-5"\h\z1GeneircIntefacegi=newGeneircInteface(){2publicIntegerm
return1;};9@Override4ethod1(Integerobj){5publicIntegerm
return1;};96}78通過(guò)匿名類(lèi)的方式,是否可以獲取Integer的泛型信息?能,匿名類(lèi)也會(huì)在進(jìn)行classcompiler保存泛型信息。假如本文例子中的methods,是放在父類(lèi)中BaseGeneircInteface中進(jìn)行申明,GenericClass中指定R為L(zhǎng)ist,是否可以獲取到對(duì)應(yīng)的泛型信息?不能,理由和問(wèn)題1類(lèi)似。備注具體泛型擦拭和信息保存,引用了撒迦的一段回復(fù),解釋的挺詳盡了。RednaxelaFX寫(xiě)道Java泛型有這么一種規(guī)律:位于聲明一側(cè)的,源碼里寫(xiě)了什么到運(yùn)行時(shí)就能看到什么;位于使用一側(cè)的,源碼里寫(xiě)什么到運(yùn)行時(shí)都沒(méi)了。什么意思呢?“聲明一側(cè)”包括泛型類(lèi)型(泛型類(lèi)與泛型接口)聲明、帶有泛型參數(shù)的方法和域的聲明。注意局部變量的聲明不算在內(nèi),那個(gè)屬于“使用”一側(cè)。Java代碼1importjava.util.List;2importjava.util.Map;34publicclassGenericClass{//15privateListlist;//26privateMap<string,t>map;//378publicUgenericMethod(Map<t,u>m){//49returnnull;10}11}上面代碼里,帶有注釋的行里的泛型信息在運(yùn)行時(shí)都還能獲取到,原則是源碼里寫(xiě)了什么運(yùn)行時(shí)就能得到什么。針對(duì)1的GenericClass,運(yùn)行時(shí)通過(guò)Class.getTypeParameters()方法得到的數(shù)組可以獲取那個(gè)“T”同理,2的T、3的java.lang.String與T、4的T與U都可以獲得。這是因?yàn)閺腏ava5開(kāi)始class文件的格式有了調(diào)整,規(guī)定這些泛型信息要寫(xiě)到class文件中。以上面的map為例,通過(guò)javap來(lái)看它的元數(shù)據(jù)可以看到記錄了這樣的信息:Javap代碼privatejava.util.Mapmap;Signature:Ljava/util/Map;Signature:length=0x2000A乍一看,privatejava.util.Mapmap;不正好顯示了它的泛型類(lèi)型被擦除了么?但仔細(xì)看會(huì)發(fā)現(xiàn)有兩個(gè)Signature,下面的一個(gè)有兩字節(jié)的數(shù)據(jù),00A。到常量池找到0乂0A對(duì)應(yīng)的項(xiàng),是:Javap代碼1const#10=AscizLjava/util/Map;;也就是內(nèi)容為“Ljava/util/Map;”的一個(gè)字符串。根據(jù)Java5開(kāi)始的新class文件格式規(guī)范,方法與域的描述符增添了對(duì)泛型信息的記錄,用一對(duì)尖括號(hào)包圍泛型參數(shù),其中普通的引用類(lèi)型用“La/b/c/D;”的格式記錄,未綁定值的泛型變量用“Txxx;”的格式記錄,其中xxx就是源碼中聲明的泛型變量名。類(lèi)型聲明的泛型信息也以類(lèi)似下面的方式記了下來(lái):Javap代碼1publicclassGenericClassextendsjava.lang.Object2Signature:length=0x2300124//...5const#18=AscizLjava/lang/Object;;詳細(xì)信息請(qǐng)參考官方文檔:/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf相比之下,“使用一側(cè)”的泛型信息則完全沒(méi)有被保留下來(lái),在Java源碼編譯到class文件后就確實(shí)丟失了。也就是說(shuō),在方法體內(nèi)的泛型局部變量、泛型方法調(diào)用之類(lèi)的泛型信息編譯后都消失了。Java代碼1importjava.util.ArrayList;2importjava.util.List;34publicclassTestClass{5publ
icstaticvoidmain
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《心臟康復(fù)培訓(xùn)》課件
- 小學(xué)一年級(jí)20以?xún)?nèi)加減法混合運(yùn)算
- 小學(xué)五年級(jí)數(shù)學(xué)小數(shù)乘除法計(jì)算練習(xí)題 集
- 二年級(jí)上冊(cè)21 雪孩子(教案)
- 2025年1月內(nèi)蒙古自治區(qū)普通高等學(xué)校招生考試適應(yīng)性測(cè)試(八省聯(lián)考)歷史試題
- 《新地產(chǎn)營(yíng)銷(xiāo)新機(jī)會(huì)》課件
- 混凝土路面施工協(xié)議書(shū)
- 口腔科護(hù)士的工作總結(jié)
- 育人為本點(diǎn)滴栽培班主任工作總結(jié)
- 浴室用品銷(xiāo)售工作總結(jié)
- 年產(chǎn)500t o-甲基-n-硝基異脲技改項(xiàng)目可研報(bào)告
- 酒店英語(yǔ)會(huì)話(huà)(第六版)教案 unit 1 Room Reservations
- 2024至2030年中國(guó)蔬菜種植行業(yè)市場(chǎng)全景監(jiān)測(cè)及投資策略研究報(bào)告
- 2024旅行社免責(zé)協(xié)議書(shū)模板范本
- 2024汽車(chē)行業(yè)社媒營(yíng)銷(xiāo)趨勢(shì)【微播易CAA中國(guó)廣告協(xié)會(huì)】-2024-數(shù)字化
- 2022-2023學(xué)年教科版五年級(jí)科學(xué)上冊(cè)期末復(fù)習(xí)資料
- DL∕T 2558-2022 循環(huán)流化床鍋爐基本名詞術(shù)語(yǔ)
- 教師進(jìn)企業(yè)實(shí)踐日志
- 抵押物變更協(xié)議范本版
- 煤矸石充填塌陷區(qū)復(fù)墾技術(shù)規(guī)程
- TSG-T7001-2023電梯監(jiān)督檢驗(yàn)和定期檢驗(yàn)規(guī)則宣貫解讀
評(píng)論
0/150
提交評(píng)論