最近看开源代码,看到里面很多Java泛型,并且通过反射去获取泛型信息。如果说要看懂泛型代码,那还是比较容易,但是如果要自己利用泛型写成漂亮巧妙的框架,那必须对泛型有足够的了解。所以这两三天就不在不断地看Java泛型相关的东西。如果说想要明白通过反射去获取泛型信息,那么Type体系是必须要了解的。Java从1.5开始引入泛型,并且也引入了Type体系。首先给出Type的类型树UML图,以便有个整体的认识。

这些都在java的reflect包下面,图中带有s的接口返回的是数组,由于画图工具的原因,标记的只有一个类型,没有带[]。可以说是Java泛型反射的基础。这个UML图我只选取了这些类与接口与Type相关的部分。

Method,Field,Constructor,Class与Type

Method,Field,Constructor都是与Type关联的,而Class是Type的子类。从实际泛型中看也是这样的,因为方法,域,构造方法都可以是泛型。

如果从来没有接触过这些,那么一开始接触这些泛型的反射会非常突兀。如果从一些疑问,或者说需求开始思考可能会能够更好地了解这些东西的作用,比如说:我们已经知道能够通过反射(从1.1就开始支持了)获得一个Class里面的方法以及域,但是我们怎么获得一个带有模版参数的Class里面的模版参数呢?比如说下面这个类

class Test<T> {
public <R> void testMethod(R params){
}
}

我们怎么根据Test.class获得T呢?获得T的具体类型?Class实现了接口GenericDeclaration。GenericDeclaration的getTypeParameters()方法就可以获得模版参数。

同样Method能够包含模版参数的地方有四个,模版参数,返回值,函数参数,异常。Method的四个方法分别对应这四个地方(有一个是继承自GenericDeclaration)。Field,Constructor也都是类似。

Method,Field,Constructor,Class都有获得声明的模版参数的方法,这样我们就可以通过反射来获取模版参数类型。

Type的子接口

Type有四个子接口:ParameterizedType,TypeVariable,WildcardType,GenericArrayType。下面分别介绍这四个类型的具体表示的意思。假设我们申明有下面这个类

public class GenericTest<T1,T2 extends Number> {
    private Map<T1 , Integer> map = null;
}

下面我们开始举例说明。

ParameterizedType

ParameterizedType是表示泛型类型,比如说Map

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">testParameterizedType</span>() throws NoSuchFieldException, SecurityException{

        Type mapGenericType = GenericTest.class.getDeclaredField(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"map"</span>).getGenericType();  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//ParameterizedType</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(mapGenericType instanceof ParameterizedType){
            Type basicType = ((ParameterizedType) mapGenericType).getRawType();

            System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"basicType equals Map.class is "</span> + (basicType ==Map.class)); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回True</span>

            System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"基本类型为:"</span>+basicType);  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Map</span>
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取泛型类型的泛型参数, 分别为 </span>
            Type[] types = ((ParameterizedType) mapGenericType).getActualTypeArguments();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < types.length; i++) {
                System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"第"</span>+(i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"个泛型类型是:"</span>+types[i]);
            }
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回为 T1, class java.lang.Integer</span>

            System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(((ParameterizedType) mapGenericType).getOwnerType());  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//null</span>
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>

TypeVariable

这个是泛型参数类型,比如Map

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">testTypeVariable</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> NoSuchFieldException, SecurityException{

        Type mapGenericType = GenericTest.class.getDeclaredField(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"map"</span>).getGenericType();  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//ParameterizedType</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(mapGenericType <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> ParameterizedType){
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取泛型类型的泛型参数, 分别为 T1, class java.lang.Integer</span>
            Type[] types = ((ParameterizedType) mapGenericType).getActualTypeArguments();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < types.length; i++) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>( types[i] <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> TypeVariable){
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// T1 is TypeVariable, and Integer is not.</span>
                    System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"the "</span>+(i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"th is TypeVariable"</span>);
                }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
                    System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"the "</span>+(i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"th is not TypeVariable"</span>);
                }
            }

        }

        System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"GenericTest TypeVariable"</span>);

        TypeVariable<Class<GenericTest>>[] typeVariables = GenericTest.class.getTypeParameters();

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// console print  T1, T2</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(TypeVariable tmp : typeVariables){
            System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>+tmp);
            Type[] bounds = tmp.getBounds(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//return upper bounds</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bounds.length > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//T2 has upper bounds which is class java.lang.Number, </span>
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//T1's upper bounds is Object which is default.</span>
                System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"bounds[0] is: "</span>+bounds[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]);
            }

            System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name is: "</span>+tmp.getName());  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//  T1, T2</span>
            System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"GenericDeclaration is equals GenericTest.class: "</span>+ (tmp.getGenericDeclaration()==GenericTest.class)); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//GenericTest</span>
        }
    }
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul>

WildcardType

WildcardType是通配符类型,也就是? extends Number这种。可以获得上下界。具体使用如下

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    private Map<? extends Number, ? super Integer> map1 = new HashMap<Integer,Integer>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    public static void testWildcardType() throws NoSuchFieldException, SecurityException{
        Type mapGenericType = GenericTest<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.class</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getDeclaredField</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"map1"</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getGenericType</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        TypeVariable<Class<GenericTest>>[] typeVariables = GenericTest<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.class</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getTypeParameters</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        Type[] types = ((ParameterizedType) mapGenericType)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getActualTypeArguments</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        for(Type t : types){
            if(t instanceof WildcardType){
                System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wildcardType"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

                if( ((WildcardType) t)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getLowerBounds</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.length</span> > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> )
                System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>((((WildcardType) t)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getLowerBounds</span>())[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; //print java.lang.Integer</span>

                if( ((WildcardType) t)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getUpperBounds</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.length</span> > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> )
                    System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>((((WildcardType) t)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getUpperBounds</span>())[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; //print java.lang.Number, Object</span>

            }
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>

GenericArrayType

这个是数组泛型。比如T1[] tArray。这是变量的声明。比如下面这段代码

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> T1[] tArray = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">testGenericArrayType</span>() throws NoSuchFieldException, SecurityException{
        Type tArrayGenericType = GenericTest.class.getDeclaredField(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"tArray"</span>).getGenericType();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(tArrayGenericType instanceof GenericArrayType){
            System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"is GenericArrayType"</span>);  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>
            Type t1 = ((GenericArrayType) tArrayGenericType).getGenericComponentType();
            System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(t1);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// print T1</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>( t1 instanceof TypeVariable){
                System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"t1 is TypeVariable"</span>);
                System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(((TypeVariable) t1).getGenericDeclaration());
            }
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

Class

Class也是实现了Type接口。像前面的代码中得到了java.lang.Integer等,就是返回Class。Class也可以通过getGenericInterfaces()获取实现的接口,通过getGenericSuperclass()获取父类的类型。

总结

整个Type体系主要就是前面介绍的内容了,从Method,Field,Class反射获取Type,然后Type本身又有很多子类型,标明具体的泛型类型。这个是我测试的代码源码

Java泛型type体系的更多相关文章

  1. Spring杂谈 | 你真的了解泛型吗?从java的Type到Spring的ResolvableType

    关于泛型的基本知识在本文中不会过多提及,本文主要解决的是如何处理泛型,以及java中Type接口下对泛型的一套处理机制,进而分析Spring中的ResolvableType. 文章目录 Type 简介 ...

  2. Java泛型之Type体系

    Type是java类型信息体系中的顶级接口,其中Class就是Type的一个直接实现类.此外,Type还有有四个直接子接口:ParameterizedType,TypeVariable,Wildcar ...

  3. 父类通过泛型获得子类Class类型 以及Type体系

    1.背景介绍 在实现SSH框架中,DAO层向数据库持久化的过程中,因为大部分保存对象的方法都会调用到sava():所有索性就把save delete update select 方法进行封装到父类中, ...

  4. 转:有关Java泛型的类型擦除(type erasing)

    转载自:拈花微笑 自从Java 5引入泛型之后,Java与C++对于泛型不同的实现的优劣便一直是饭后的谈资.在我之前的很多training中,当讲到Java泛型时总是会和C++的实现比较,一般得出的结 ...

  5. Java泛型总结

    1. 什么是泛型?泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的 ...

  6. Java——泛型

    前言 一般的类和方法,使用的都是具体的类型:基本类型或者自定义的类.如果我们要编写出适用于多种类型的通用代码,那么肯定就不能使用具体的类型.前面我们介绍过多态,多态算是一种泛化机制,但是也会拘泥于继承 ...

  7. Java基础学习总结(83)——Java泛型总结

    1. 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型 ...

  8. Java基础系列二:Java泛型

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 一.泛型概述 1.定 ...

  9. Java 干货之深入理解Java泛型

    一般的类和方法,只能使用具体的类型,要么是基本类型,要么是自定义的类.如果要编写可以应用多中类型的代码,这种刻板的限制对代码得束缚会就会很大. ---<Thinking in Java> ...

随机推荐

  1. 基于Nginx服务器和iOS9的HTTPS安全通信

    简介 在网络通信中,使用抓包软件可以对网络请求进行分析,并进行重放攻击,重放攻击的解决方案一般是使用一个变化的参数,例如RSA加密的时间戳,但考虑到网络传输时延,时间戳需要有一定的误差容限,这样仍然不 ...

  2. Java基本语法-----java标识符

    1什么是标识符 就是程序员在定义java程序时,自定义的一些名字,例如helloworld 程序里关键字class 后跟的Demo,就是我们定义的类名.类名就属于标识符的一种. 标识符除了应用在类名上 ...

  3. 贪婪算法(Greedy algorithm)-算法学习之旅(一)

    我研一下学期选修了网络管理,因为是限选课所以我没有认真上课,今天因为快结课考试了,我才去,然后我发现了一个大秘密...... 原来老师从第三节课已经开始讲算法导论的知识了,我是不是错过了什么... 废 ...

  4. octave installation on RHEL6.4

    octave installation on RHEL6.4 rhel6.4上安装octave GNU Octave 是一种高级语言,主要设计用来进行数值计算,它是 MathWorks 出品的 Mat ...

  5. Ext JS 6开发实例(四) :调整主视图

    上文把主界面设置好,但是主视图因为界面的微调出现了显示问题,本文将把它调整好了. 打开app/view/main/Main.js,可以看到主视图是派生于标签面板(Ext.tab.Panel)的.在视图 ...

  6. Tapestry: Obtained resource by @Inject is NULL

    Issue: When you inject some resources by @Inject Annotation in Tapestry Page or other components, yo ...

  7. UNIX网络编程——套接字选项(SOL_SOCKET级别)

    #include <sys/socket.h> int setsockopt( int socket, int level, int option_name,const void *opt ...

  8. Rational Rose正逆向工程(类图转Java代码,Java代码转类图)

     一,正向工程     1.设置默认语言为Java,Tools->Options->Notation->default:选择Java.         2.设置环境变量Class ...

  9. 《java入门第一季》之集合toString源码解析

    代码: Collection c = new ArrayList(); c.add("hello"); c.add("world"); c.add(" ...

  10. Android的加速度传感器模拟摇一摇的效果-android学习之旅(66)

    主要介绍一下android的加速传感器的简单用法,模拟摇一摇 ,如果x,y,z三个方向的加速度超过了15,就会弹出Toast,当然你可以设置更复杂的策略,比如判断间隔 代码如下 public clas ...