class A extends B<C> {
...
}
class B<T extends E> {
...
public D<T> field;
}如何从"field“反射中获取"C”类?
现在我只能获得"B“类字段作为"A”超类字段,并且看起来他们不知道哪个类型参数是从"A“传递的,并且只显示类型"E”。
发布于 2018-07-16 21:11:19
尽管A使用具体类型C扩展了B,但这并不会改变您从反射中获得的B字段的类型。
但是,您可以手动将字段的类型变量映射到具体类型。首先为A类构建TypeVariable到具体类型的映射,然后使用该映射将B中的类型变量转换为具体类型。
Class<?> cls = A.class; // using `A` as an example
Class<?> sup = cls.getSuperclass();
// TypeVariables of `B`
TypeVariable<?>[] tv = sup.getTypeParameters();
// Concrete types used to extend with in `A`
Type[] actual = ((ParameterizedType) cls.getGenericSuperclass()).getActualTypeArguments();
Map<TypeVariable<?>, Type> mappings // map one to the other
= IntStream.range(0, tv.length)
.boxed()
.collect(Collectors.toMap(i -> tv[i], i -> actual[i]));
for(Field f : sup.getDeclaredFields()) {
Type t1 = f.getGenericType();
System.out.println(t1); // prints `D<T>`
Type t2 = concretify(t1, mappings);
System.out.println(t2); // prints `D<C>`
}public static Type concretify(Type from, Map<TypeVariable<?>, Type> mappings) {
if(from instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) from;
Type[] ts = pt.getActualTypeArguments();
Type[] result = new Type[ts.length];
for (int i = 0; i < ts.length; i++) {
result[i] = mappings.getOrDefault(ts[i], ts[i]);
}
return new ParameterizedType() { // some ParameterizedType implementation
@Override
public Type getRawType() {
return pt.getRawType();
}
@Override
public Type getOwnerType() {
return pt.getOwnerType();
}
@Override
public Type[] getActualTypeArguments() {
return result;
}
@Override
public String toString() {
return String.format("%s<%s>", getRawType().getTypeName(),
Arrays.stream(getActualTypeArguments())
.map(Type::getTypeName)
.collect(Collectors.joining(",")));
}
};
}
return from;
}https://stackoverflow.com/questions/51362110
复制相似问题