可能的重复项:
获取 Java 中泛型参数的类型(带反射
( 在运行时获取类的泛型类型
假设我有这样的类:
public class Foo<T, M> {
Pair<T, M> bar;
}
有没有办法确定运行时的"T"和"M"是什么? 例如
Foo<String, Integer> foo1 = new Foo<String, Integer>();
Foo<Integer, Boolean> foo2 = new Foo<Integer, Boolean>();
// what happens next?
谢谢!
No. 没有。 这几乎就是类型擦除的定义。
也就是说,有一些时髦的解决方法。 您可以显式查找该对的组件,并询问它们的类型。 你可以对匿名内部类使用很酷的技巧,例如 Guava 的 TypeToken
使用——你不能在运行时确定new Foo<String, Integer>()
的类型,但你可以在运行时确定new Foo<String, Integer>() {}
的类型——注意匿名内部类,它保留了为其超类指定的泛型参数,即 Foo
。 (披露:我为番石榴做出贡献。
通常,最好的解决方案是首先避免需要这些信息。 没有关于如何做到这一点的一般食谱,但通常是可能的。
综上所述,满足此需求的唯一通用解决方案是显式传递Class
元数据。
运行时泛型信息将被擦除。一旦你的类编译,所有泛型类型信息将被擦除和替换:
泛型类型中的所有类型参数及其边界或 Object (如果类型参数是无边界的(
实际上,java.lang.reflect.Field
保留了泛型信息;因此,通过反射,您可以获得泛型信息,但仅适用于类/实例变量(不是方法返回类型,也不是局部变量(。
所以在你的例子中,如果 foo1 和 foo2 是某个类中的实例变量:
class FooTest {
Foo<String, Boolean> foo1;
}
然后FooTest.class.getDeclaredField("foo1").getGenericType()
将返回一个ParameterizedType
实例,您可以在其中检查getActualTypeArguments()
。