Java 怎么获取传入泛型类的具体类型?

在 Java 反射中,对于一般的类,我们可以通过对象.getClass来获得类对象,然后通过类对象.getFields()可以获得类下的字段对象数组,以及字段对象.getType()来获得字段的具体类型,如下面源码中carClass.getFields()[0].getType():int

但如果是泛型类(参见源码中的Foo类),因为其具体类型是外部传入的,引起 Java反射是无法获取到传入泛型的具体类型的,如字段对象.getType输出 Object(参见源码中输出fooClass.getFields()[0].getType():class java.lang.Object

Gson的TypeToken解决了 Java 泛型反射问题,通过定义一个匿名内部类new TypeToken>(){},然后可以获取具体的泛型类型。

源码如下:

package test.onjava;

import com.google.gson.reflect.TypeToken;

class TestGeneric {

    class Car {
        public int wheel;
        protected int color; // carClass.getFields().length 不包含这个
    }

    class Foo {
        public T value;
        public String key;
    }

    void testGeneric(){
        // 一般类
        System.out.println("-----------------------Normal class--------");
        Car car = new Car();
        Class carClass = car.getClass();

        System.out.println("                    car.getClass():" + carClass);

        System.out.println("       carClass.getFields().length:" + carClass.getFields().length);

        System.out.println(" carClass.getFields()[0].getType():" + carClass.getFields()[0].getType());

        // 泛型类
        System.out.println("-----------------------Generic class--------");
        Foo foo = new Foo();
        Class fooClass = foo.getClass();

        System.out.println("                    foo.getClass():" + fooClass);

        System.out.println("       fooClass.getFields().length:" + fooClass.getFields().length);

        System.out.println(" fooClass.getFields()[0].getType():" + fooClass.getFields()[0].getType());


        // Gson
        System.out.println("----------------------Gson TypeToken---------");
        TypeToken typeToken= new TypeToken>(){};

        System.out.println("             typeToken.getRawType:" + typeToken.getRawType());

        System.out.println("                typeToken.getType:" + typeToken.getType());
    }

}

输出

-----------------------Normal class--------
                    car.getClass():class test.onjava.TestGeneric$Car
       carClass.getFields().length:1
 carClass.getFields()[0].getType():int
-----------------------Generic class--------
                    foo.getClass():class test.onjava.TestGeneric$Foo
       fooClass.getFields().length:2
 fooClass.getFields()[0].getType():class java.lang.Object
----------------------Gson TypeToken---------
             typeToken.getRawType:class test.onjava.TestGeneric$Foo
                typeToken.getType:test.onjava.TestGeneric$Foo

你可能感兴趣的:(Java 怎么获取传入泛型类的具体类型?)