【发布时间】:2014-02-11 01:30:03
【问题描述】:
post I found by Ian Robertson 有一个很好的实用方法来确定 Java 类类型参数的运行时类。它比快速版本更进一步:
ParameterizedType pt = (ParameterizedType)this.getClass().getGenericSuperclass();
Class<?> c = (Class<?>) pt.getActualTypeArguments()[0]
对于从抽象参数化父 (class Foo<T> extends Bar<T>) 或参数化抽象类 (new Foo<Bar>() {}) 的匿名实例继承的参数化子代,这两种方法都像一个魅力,并使用具体类型进行实例化。
我失败的地方是尝试对通过类型参数实例化的其他对象做同样的事情。相关的类对象是:
public class Foo {/* code omitted for brevity */}
public class MyFoo extends Foo {/* code omitted for brevity */}
public abstract class AbstractLoader<T extends Foo> {/* code omitted for brevity */}
public abstract class AbstractReader<T extends Foo> {/* code omitted for brevity */}
public class MyReader<T extends Foo> extends AbstractReader<T> {/* code omitted for brevity */}
public class Loader<T extends Foo> extends AbstractLoader<T> {
/* code omitted for brevity */
public MyReader<T> getReader() {
// Parameterized type "T" doesn't seem to carry through here
return new MyReader<T>();
}
}
示例代码:
static void main(String... s) {
Loader<MyFoo> loader = new Loader<>(); // new Loader<MyFoo>() for Java < 1.7
MyReader<MyFoo> = loader.getReader();
ParameterizedType pt = (ParameterizedType)loader.getClass().getGenericSuperclass();
System.out.println("LoaderType = " + pt.getActualTypeArguments()[0]);
// Prints: LoaderType = MyFoo
pt = (ParameterizedType)reader.getClass().getGenericSuperclass();
System.out.println("ReaderType = " + pt.getActualTypeArguments()[0]);
// Prints: ReaderType = T
}
直觉告诉我这个“应该”以某种方式是可能的,但我似乎无法找到正确的答案。 OTOH,这可能是由于类型擦除而“无法做到”的另一个例子。
【问题讨论】:
-
请发帖SSCCE。您现有的示例不完整并且存在编译错误。特别是,
loader的泛型类型不应该是可具体化的 - 你需要做new Loader<MyFoo>() { }。 -
Paul,我已经更新了示例代码;对于那个很抱歉。我确实尝试了
new Loader<>()和new Loader<MyFoo()并得到了相同的结果。 -
您的示例仍然是错误的 - 它打印“LoaderType = T ReaderType = T”(在修复
reader声明之后)。请确保您的问题的前提是有道理的,或者删除它。
标签: java generics reflection runtime