当我运行(ParameterizedType)的getClass()getGenericSuperclass(), 想到被T,但它的PropertyEditorSupport,并且不能被强制转换为 ParameterizedType;
如果您想要访问T
(即类型参数),则适当的反射方法是Class.getTypeParameters
。
// Test.java:
class Generic<T> {
}
class Main {
public static void main(String[] args) {
final Generic<Integer> gint1 = new Generic<Integer>();
System.err.println("gint1's type-parameter: "
+ gint1.getClass().getTypeParameters()[0]);
}
}
如果你运行你上面得到下面的代码:
$ javac Test.java
$ java Main
gint1's type-parameter: T
注意,类型参数未解析为整数,但作为T
因为这种信息无法在运行时。
如果访问这些信息对您很重要,那么您有两个简单的选项。
A.对象包含实际类型的类的引用:
class Generic<T> {
public final Class<T> type;
public Generic(Class<T> type) {
this.type = type;
}
public Class<T> type() {
return type;
}
}
class Main {
public static void main(String[] args) {
final Generic<Integer> gint2 = new Generic<>(Integer.class);
System.err.println("gint2's type-parameter: " + gint2.type().getSimpleName());
}
}
// Output will be "gint2's type-parameter: Integer".
B.你创建一个子类,给出了一个具体的类为该类型的参数:
import java.lang.reflect.*;
class Generic<T> {
}
class IntegerGeneric extends Generic<Integer> {
}
class Main {
public static void main(String[] args) {
final Generic<Integer> gint3 = new IntegerGeneric();
final Generic<Double> gint4 = new Generic<Double>() {};
System.err.println("gint3's type-parameter: "
+ ((ParameterizedType)gint3.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
System.err.println("gint4's type-parameter: "
+ ((ParameterizedType)gint4.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
}
}
// Output:
// gint3's type-parameter: class java.lang.Integer
// gint4's type-parameter: class java.lang.Double
注意gint4类不是Generic<Double>
,而是由匿名内部类扩展它,由于构造函数后面的{}
...这是完整的class DoubleGeneric ...
声明的替代方法。
在这两个替代方案中,A.和B.,A.因为通常应该避免依赖反思;除此之外,它更容易隐藏运行时错误,代码更难以维护。
我想知道有什么不同,当使用 (ParameterizedType)的getClass()。getGenericSuperclass()一类具有 一个没有泛型类型的超类。
如果您查找的Type
文档,类此方法返回的引用,它表示这是一个“保护伞”超级接口为所有对象/数据类型可以在Java语言中甚至包括primitives ...所以对于没有泛型超类的类我想它会返回一个反映该类型的子类...
一个快速实验显示,实际上它会返回一个'Class'对象它相当于getSuperclass()。
也许其他人可以对此有更多的了解,但我认为这可能有点误会......我认为getSuperType()或类似的东西会更合适。也许最初它只支持较旧的Java版本(1.5版本)中的泛型,并最终扩展到涵盖其他数据类型,但这是我的一个猜测,而没有考虑它的历史。
泛型是编译时安全检查。它们在运行时不包含任何可用的类型信息。 – 4castle
@ 4castle但是,如果'RequestDataEditor'类没有父类,那么我们可以得到泛型类型 – JackYe
如果删除'extends PropertyEditorSupport','getGenericSuperclass()'只返回'class Object'。请提供[mcve]进行测试。 – kennytm