反思:将声明 class 的类型参数应用于字段

Reflection: Applying type parameters of declaring class to fields

我有以下 class 结构:

class A<T,R> {
   B<R> b;
......
}

class B<R> {
   R t;
}

class StringConsumer {
   A<String, String> a;
}

class LongConsumer {
   A<Long, Long> a;
}

鉴于我有一个消费者 classes 的实例,是否可以获得 consumer.a.b 的类型参数?我发现如果我将 a 声明为 StringA a;,其中 class StringA extends A<String, String> 使用 TypeTools

,我可以解决相同的问题

由于您的消费者 类 声明了没有类型变量的字段 a,您需要的所有类型信息都将在运行时出现。

虽然直接使用反射可以实现您的要求,但它变得非常快,所以我强烈建议使用 GenTyRef or GeAnTyRef(我维护的增强版)。

StringConsumer consumer = new StringConsumer(); //Or LongConsumer

Field a = consumer.getClass().getDeclaredField("a");
//typeOfA represents A<String, String>
ParameterizedType typeOfA = (ParameterizedType) GenericTypeReflector.getExactFieldType(a, consumer.getClass());

Type[] args =  typeOfA.getActualTypeArguments();
System.out.println(args[0]); //String
System.out.println(args[1]); //String

Field b = A.class.getDeclaredField("b");
//or if you need it dynamic ((Class)typeOfA.getRawType()).getDeclaredField("b")
//or GenericTypeReflector.erase(typeOfA).getDeclaredField("b")
//typeOfB represents B<String>
ParameterizedType typeOfB = (ParameterizedType) GenericTypeReflector.getExactFieldType(b, typeOfA);
System.out.println(typeOfB.getActualTypeArguments()[0]); //String again

所以你在这里做的是从 StringConsumer 开始,获取其字段 a 的类型(typeOfA,即 A<String, String>),然后使用该信息获取字段类型 btypeOfB,即 B<String>)。 您可以通过这种方式深入了解...