這裏沒有圖片,看原文,講解的挺好。數組
上一篇,提到了Java-Type體系,對Type類型進行了簡單的講解;本篇,就用代碼的方式,對其中的5大類型:原始類型(Class)、參數化類型(ParameterizedType)、數組類型(GenericArrayType)、類型變量(TypeVariable)、基本類型(Class) 進一步說明;this
ParameterizedType表示參數化類型,也就是泛型,例如List<T>、Set<T>等;spa
ParameterizedType.net
在ParameterizedType接口中,有3個方法,分別是getActualTypeArguments()、 getRawType()、 getOwnerType();code
獲取泛型中的實際類型,可能會存在多個泛型,例如Map<K,V>,因此會返回Type[]數組;對象
值得注意的是,不管<>中有幾層嵌套(List<Map<String,Integer>),getActualTypeArguments()方法永遠都是脫去最外層的<>(也就是List<>),將口號內的內容(Map<String,Integer>)返回;接口
咱們常常遇到的List<T>,經過getActualTypeArguments()方法,獲得的返回值是TypeVariableImpl對象,也就是TypeVariable類型(後面介紹);圖片
獲取聲明泛型的類或者接口,也就是泛型中<>前面的那個值;get
經過方法的名稱,咱們大概瞭解到,此方法是獲取泛型的擁有者,那麼擁有者是個什麼意思?源碼
Returns a {@code Type} object representing the type that this type * is a member of. For example, if this type is {@code O.I}, * return a representation of {@code O}. (摘自JDK註釋)
經過註解,咱們得知,「擁有者」表示的含義--內部類的「父類」,經過getOwnerType()方法能夠獲取到內部類的「擁有者」;例如: Map 就是 Map.Entry<String,String>的擁有者;
泛型數組類型,例如List<String>[] 、T[]等;
GenericArrayType
在GenericArrayType接口中,僅有1個方法,就是getGenericComponentType();
返回泛型數組中元素的Type類型,即List<String>[] 中的 List<String>(ParameterizedTypeImpl)、T[] 中的T(TypeVariableImpl);
值得注意的是,不管是幾維數組,getGenericComponentType()方法都只會脫去最右邊的[],返回剩下的值;
泛型的類型變量,指的是List<T>、Map<K,V>中的T,K,V等值,實際的Java類型是TypeVariableImpl(TypeVariable的子類);此外,還能夠對類型變量加上extend限定,這樣會有類型變量對應的上限;
TypeVariable
在TypeVariable接口中,有3個方法,分別爲getBounds()、getGenericDeclaration()、getName();
得到該類型變量的上限,也就是泛型中extend右邊的值;例如 List<T extends Number> ,Number就是類型變量T的上限;若是咱們只是簡單的聲明瞭List<T>(無顯式定義extends),那麼默認爲Object;
無顯式定義extends:
值得注意的是,類型變量的上限能夠爲多個,必須使用&符號相鏈接,例如 List<T extends Number & Serializable>;其中,& 後必須爲接口;
獲取聲明該類型變量實體,也就是TypeVariableTest<T>中的TypeVariableTest;
獲取類型變量在源碼中定義的名稱;
說到TypeVariable類,就不得不說起Java-Type體系中另外一個比較重要的接口---GenericDeclaration;含義爲:聲明類型變量的全部實體的公共接口;也就是說該接口定義了哪些地方能夠定義類型變量(泛型);
經過查看源碼發現,GenericDeclaration下有三個子類,分別爲Class、Method、Constructor;也就是說,咱們定義泛型只能在一個類中這3個地方自定義泛型;
此時,咱們不由要問,咱們不是常常在類中的屬性聲明泛型嗎,怎麼Field沒有實現 GenericDeclaration接口呢?
其實,咱們在Field中並無聲明泛型,而是在使用泛型而已!不信,咱們實際上代碼來看看!
1.首先在Class上定義泛型:
Class定義泛型
2.咱們沒有在Class上定義泛型,直接在構造方法上定義泛型
泛型構造
3.一樣沒有在Class定義泛型,直接在普通方法上定義泛型
泛型方法
3.咱們直接在屬性上定義
屬性上定義泛型
咱們看到,若是不在Class上定義,屬性上並不能直接使用!因此,這也是我以前說的屬性上並非定義泛型,而是使用泛型,因此Field並無實現GenericDeclaration接口!
Type接口的實現類,是咱們工做中經常使用到的一個對象;在Java中,每一個.class文件在程序運行期間,都對應着一個Class對象,這個對象保存有這個類的所有信息;所以,Class對象也稱之爲Java反射的基礎;
Class
經過上面的例子,能夠看出,當咱們沒有聲明泛型的時候,咱們普通的對象就是一個Class類型,是Type中的一種;
?---通配符表達式,表示通配符泛型,可是WildcardType並不屬於Java-Type中的一鍾;例如:List<? extends Number> 和 List<? super Integer>;
WildcardType
在WildcardType接口中,有2個方法,分別爲getUpperBounds()、getLowerBounds();
獲取泛型變量的上邊界(extends)
獲取泛型變量的下邊界(super)
以上,就是對Java-Type體系中相關對象的介紹;
做者:賈博巖 連接:http://www.jianshu.com/p/e8eeff12c306 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。