关于Java中类型擦除处理的大多数文档假定用例正在处理类似SomeType<ParamType>
的类型。
我正在尝试处理以下方法的方法参数:
public void setOtherReferenceRanges(List<ReferenceRange<T>> referenceRanges)
当使用类型DvQuantity实例化容器类时,此签名应该成为
运行时public void setOtherReferenceRanges(List<ReferenceRange<DvQuanitity>> referenceRanges)
。
使用反射可以看到List
的{{1}}为actualTypeArgument
。由于反射使用类信息,我不希望它给我ReferenceRange<T>
。
但是,当我创建包含此方法的类时,我将ReferenceRange<DvQuantity>
类型作为DvQuantity
传递。因此,T
中的类型填充应该可供Java运行时使用,但我找不到获取它的方法。我最终得到了一个通过反射访问的T
对象,它似乎不包含任何有用的数据。
您能想到在运行时发现此信息的任何方法吗?
答案 0 :(得分:1)
当你说
时当我创建包含此方法的类
时
我猜您的意思是在创建该类型的对象时,例如:
foo = new ContainerClass<DvQuantity>();
在这种情况下,由于删除,无法恢复DvQuantity
类型。
但是,如果你创建一个类将类型参数传递给超类,就像这样
class DvQuantityContainerClass extends ContainerClass<DvQuantity> {...}
...
foo = new DvQuantityContainerClass();
或者,更短,一个内联匿名子类(看起来几乎像第一个例子,但有一个微妙但重要的区别):
foo = new ContainerClass<DvQuantity>(){};
然后,您可以恢复type参数,因为您恢复了用于在运行时扩展超类的类型参数。遗憾的是,Java本身并没有提供一种简单的方法来获取填充了DvQuantityContainerClass.setOtherReferenceRanges
的{{1}}方法的类型。为此,我编写了gentyref来做高级操作对泛型类型的反思:
T
答案 1 :(得分:0)
通用类型信息是erased by the compiler,在运行时不可用。当我需要在运行时确保某种类型时,我传入一个类参数:
public <T> void doSomething(T t, Class<T> c);
这并不总是方便甚至可能,但在很多情况下都是可能的。
答案 2 :(得分:0)
因此,T的类型填充应该可用于Java运行时,但我找不到获取它的方法。
也许这不完全正确,但我想到的方式是在运行时没有实际的类 - 只是一个没有特定类型的对象,它符合T的接口。换句话说,擦除不是与对象发生的,而是与这些模糊的(至少在OOP世界中)类型的东西。
http://java.sun.com/docs/books/tutorial/java/generics/erasure.html
有一些方法可以捕获类本身内部的类型信息(T类型需要一个方法getUnderlyingType()...或者其他东西),但这是一个坏主意。如果你真的需要原始类型的对象,我会重新考虑使用泛型。