反思:将声明 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>
),然后使用该信息获取字段类型 b
(typeOfB
,即 B<String>
)。
您可以通过这种方式深入了解...
我有以下 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>
),然后使用该信息获取字段类型 b
(typeOfB
,即 B<String>
)。
您可以通过这种方式深入了解...