Java:在嵌套参数化类型中获取内部类型(反射)

mah*_*nya 5 java generics reflection nested

关于Java中类型擦除处理的大多数文档假定用例正在处理类似的类型SomeType<ParamType>.我正在尝试处理以下方法的方法参数:

public void setOtherReferenceRanges(List<ReferenceRange<T>> referenceRanges)
Run Code Online (Sandbox Code Playgroud)

当使用类型DvQuantity实例化容器类时,此签名应该 public void setOtherReferenceRanges(List<ReferenceRange<DvQuanitity>> referenceRanges)在运行时.

使用反射可以看出它List具有的actualTypeArgumentReferenceRange<T>.由于反射使用类信息,我不希望它给我ReferenceRange<DvQuantity>.但是,当我创建包含此方法的类时,我将DvQuantity类型传递为T.所以TJava运行时应该可以使用填充类型,但我找不到获取它的方法.我最终得到了一个TypeVariableImpl通过反射访问的对象,它似乎不包含任何有用的数据.

你能想到在运行时发现这些信息的方法吗?

Wou*_*rts 1

当你说

当我创建包含此方法的类时

我猜你的意思是当你创建该类型的对象时,例如:

foo = new ContainerClass<DvQuantity>();
Run Code Online (Sandbox Code Playgroud)

在这种情况下,由于擦除,无法恢复类型DvQuantity

但是,如果您创建一个类,将类型参数传递给超类,如下所示

class DvQuantityContainerClass extends ContainerClass<DvQuantity> {...}
...
foo = new DvQuantityContainerClass();
Run Code Online (Sandbox Code Playgroud)

或者,更短地说,一个内联匿名子类(看起来几乎像第一个示例,但有一个微妙但重要的区别):

foo = new ContainerClass<DvQuantity>(){};
Run Code Online (Sandbox Code Playgroud)

然后您可以恢复类型参数,因为您可以恢复用于在运行时扩展超类的类型参数。不幸的是,Java 本身并没有提供一种简单的方法来获取DvQuantityContainerClass.setOtherReferenceRanges填充的方法的类型T。为此,我编写了gentyref,对泛型类型进行高级反射:

Method m = DvQuantityContainerClass.class.getMethod("setOtherReferenceRanges", List.class);
// this will return List<ReferenceRange<DvQuanity>>, like you are lookingn for
return GenericTypeReflector.getExactParameterTypes(m, DvQuantityContainerClass.class)
Run Code Online (Sandbox Code Playgroud)