Java泛型type體系整理_第1頁(yè)
Java泛型type體系整理_第2頁(yè)
Java泛型type體系整理_第3頁(yè)
Java泛型type體系整理_第4頁(yè)
Java泛型type體系整理_第5頁(yè)
已閱讀5頁(yè),還剩9頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(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ì)象的類型定義類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說明:Type:TypeisthecommonsuperinterfaceforalltypesintheJavaprogramminglanguage.Theseincluderawtypes,parameterizedtypes,arraytypes,typevariablesandprimitivetypes.使用一般我們不直接操作Type類型,所以第一次使用會(huì)對(duì)這個(gè)比較陌生,相對(duì)內(nèi)部的一些概念。根據(jù)Type類型分類,整理了一個(gè)type->class的轉(zhuǎn)換過程,同理也包括處理GenericType。支持多級(jí)泛型處理。Java代碼1privatestaticClassgetClass(Typetype,inti)(if(typeinstanceofParameterizedType){//處

理泛型類型returngetGenericClass((Param理泛型類型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();//父類的泛型信息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é)果說明:

因?yàn)榉盒偷牟潦?,?duì)應(yīng)的GeneircInteface和BaseGeneircInteface,在源碼信息已被擦除對(duì)應(yīng)的類型,進(jìn)行了upper轉(zhuǎn)型,所以取到的是Object??梢允褂胑xtendsGenericClass在類定義時(shí),聲明了繼承父接口的泛型為L(zhǎng)ist,所以再通過接口和父類獲取泛型信息時(shí),是能正確的獲取。通過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)泛型信息是沒有的。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思考問題: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通過匿名類的方式,是否可以獲取Integer的泛型信息?能,匿名類也會(huì)在進(jìn)行classcompiler保存泛型信息。假如本文例子中的methods,是放在父類中BaseGeneircInteface中進(jìn)行申明,GenericClass中指定R為L(zhǎng)ist,是否可以獲取到對(duì)應(yīng)的泛型信息?不能,理由和問題1類似。備注具體泛型擦拭和信息保存,引用了撒迦的一段回復(fù),解釋的挺詳盡了。RednaxelaFX寫道Java泛型有這么一種規(guī)律:位于聲明一側(cè)的,源碼里寫了什么到運(yùn)行時(shí)就能看到什么;位于使用一側(cè)的,源碼里寫什么到運(yùn)行時(shí)都沒了。什么意思呢?“聲明一側(cè)”包括泛型類型(泛型類與泛型接口)聲明、帶有泛型參數(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í)都還能獲取到,原則是源碼里寫了什么運(yùn)行時(shí)就能得到什么。針對(duì)1的GenericClass,運(yùn)行時(shí)通過Class.getTypeParameters()方法得到的數(shù)組可以獲取那個(gè)“T”同理,2的T、3的java.lang.String與T、4的T與U都可以獲得。這是因?yàn)閺腏ava5開始class文件的格式有了調(diào)整,規(guī)定這些泛型信息要寫到class文件中。以上面的map為例,通過javap來(lái)看它的元數(shù)據(jù)可以看到記錄了這樣的信息:Javap代碼privatejava.util.Mapmap;Signature:Ljava/util/Map;Signature:length=0x2000A乍一看,privatejava.util.Mapmap;不正好顯示了它的泛型類型被擦除了么?但仔細(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開始的新class文件格式規(guī)范,方法與域的描述符增添了對(duì)泛型信息的記錄,用一對(duì)尖括號(hào)包圍泛型參數(shù),其中普通的引用類型用“La/b/c/D;”的格式記錄,未綁定值的泛型變量用“Txxx;”的格式記錄,其中xxx就是源碼中聲明的泛型變量名。類型聲明的泛型信息也以類似下面的方式記了下來(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è)”的泛型信息則完全沒有被保留下來(lái),在Java源碼編譯到class文件后就確實(shí)丟失了。也就是說,在方法體內(nèi)的泛型局部變量、泛型方法調(diào)用之類的泛型信息編譯后都消失了。Java代碼1importjava.util.ArrayList;2importjava.util.List;34publicclassTestClass{5publ

icstaticvoidmain

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論