使用 Java Reflections 获取通用类字段类型

dar*_*bit 4 java generics reflection

我有以下类结构:

public class GenClass<T> {
    public T elem;
}
Run Code Online (Sandbox Code Playgroud)

我按以下方式使用它:

public class Test {
    public GenClass<UUID> data;
Run Code Online (Sandbox Code Playgroud)

现在我想使用 data( ) 的 Field 对象获取 elem 的类型,Test.class.getField("data")但是当我用来getType检索类时,通用信息被剥离。

如何将通用信息映射getGenericType到类对象以检索具有正确类型的字段?

编辑:由于存在一些误解,我尝试澄清我的问题。考虑这个例子:

public class AClass<T, Q> {
    public Q elem;
    // some other code using T...
}

public class BClass<T, Q> {
    public T elem;
    // some other code using Q...
}
Run Code Online (Sandbox Code Playgroud)

现在我想要一个函数来获取 elem 的类:

public class Test {
    public AClass<UUID, String> a;
    public BClass<Integer, Float> b;

    void do() throws Exception {
        Field aField = Test.class.getField("a");
        Field bField = Test.class.getField("b");

        getType(aField, "elem"); // should return String.class
        getType(bField, "elem"); // should return Integer.class
    }

    Class<?> getType(Field f, String classField) {
        // ???
    } 
}
Run Code Online (Sandbox Code Playgroud)

我需要如何实施getType才能得到我想要的结果?

rge*_*man 5

通过调用,您拥有Type与您的字段相对应的对象。datagetGenericType

Type t = f.getGenericType();  // f is your Field
Run Code Online (Sandbox Code Playgroud)

接口及其实现代表了此处可能存在Type的类型的不同情况。因为data的类型是GenClass<UUID>,用类型参数进行参数化,所以Type这里返回的实际上是一个ParameterizedType。

ParameterizedType pt = (ParameterizedType) t;
Run Code Online (Sandbox Code Playgroud)

一般来说,可能有多个泛型类型参数,但这里只有一个。调用ParameterizedType的getActualTypeArguments方法。

Type parameter = pt.getActualTypeArguments()[0];
Run Code Online (Sandbox Code Playgroud)

是的,我们有另一个Type实例,但这个实例代表 的泛型类型参数Field,而不是其Field本身。因为您在类中提供了一个类类型Test,所以这Type只不过是一个普通的Class-- UUID.class。

System.out.println(parameter instanceof Class);
System.out.println(parameter == UUID.class);
Run Code Online (Sandbox Code Playgroud)

输出:

true
true
Run Code Online (Sandbox Code Playgroud)