繁体   English   中英

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

[英]Java: getting inner type in nested parameterized types (reflection)

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

public void setOtherReferenceRanges(List<ReferenceRange<T>> referenceRanges)

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

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

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

当你说

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

我猜你的意思是当你创建一个这种类型的对象时,例如:

foo = new ContainerClass<DvQuantity>();

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

但是,如果你创建一个传递一个类型参数的超类,像这样

class DvQuantityContainerClass extends ContainerClass<DvQuantity> {...}
...
foo = new DvQuantityContainerClass();

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

foo = new ContainerClass<DvQuantity>(){};

然后,您可以恢复type参数,因为您恢复了用于在运行时扩展超类的类型参数。 遗憾的是,Java本身并没有提供一种简单的方法来获得填充了TDvQuantityContainerClass.setOtherReferenceRanges方法的类型。为此,我编写了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)

通用类型信息由编译器擦除,在运行时不可用。 当我需要在运行时确保某种类型时,我传入一个类参数:

public <T> void doSomething(T t, Class<T> c);

这并不总是方便甚至可能,但在许多情况下它是可能的。

所以T中的类型填充应该可用于Java运行时,但我找不到获取它的方法。

也许它并不完全正确,但我想到的方式是在运行时没有实际的类 - 只是没有特定类型的对象满足T的接口。换句话说,擦除不是用对象发生的,而是用这些模糊的(至少在OOP世界中)类型的东西。

http://java.sun.com/docs/books/tutorial/java/generics/erasure.html

有一些方法可以捕获类本身内部的类型信息(T类型需要一个方法getUnderlyingType()...或者其他东西),但这是一个坏主意。 如果你真的需要原始类型的对象,我会重新考虑使用泛型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM