给出一个班级
class EnvironmentHolder<V> {
protected Map<String,V> environment;
// Get the Type of V via Google's GSon library; this part
// works okay
protected final Type VALUE_TYPE = new TypeToken<V>() {}.getType();
...
public void importEnvironment(Class aClass) {
// NEEDS AN IMPLEMENTATION
}
}
其中V
是某种引用类型,我正在尝试收集所有的引用类型
aClass
的静态成员,可以“赋予”一类类型
V
- 即那些是子类,实现或者
与V
相同的班级。
我该怎么做?我想对importEnvironment
使用以下实现:
for (Field field : aClass.getFields()) {
((Class) V).isAssignableFrom(field.getType())
}
我看到Class
确实是Type
的实施者,但我不是
确定如何安全地进行演员表演。 (Type
也包括在内
非引用类型,不是Class
es。)
注意:请不要说,“类型擦除会妨碍在运行时执行此操作” 直到你想到了。相当多的问题都是一个几乎是自动的响应,这似乎意味着反射API无法在Java中实现。
谢谢!
答案 0 :(得分:2)
由于类型擦除,您不能使用现有代码执行此操作:您不知道V
在运行时是什么。
您需要Class<V>
的实例,因此您可以说:
clazz.isAssignableFrom(field.getType());
您可以将其作为EnvironmentVariable<V>
的构造时参数传递,也可以将其作为importEnvironment
的另一个参数传递。我说前者更方便,因为你只需要做一次,而不是每当你调用importEnvironment
时。
class EnvironmentHolder<V> {
private final Class<V> clazz;
EnvironmentHolder(Class<V> clazz) {
this.clazz = clazz;
}
public void importEnvironment(Class<?> aClass) {
for (Field field : aClass.getFields()) {
if (clazz.isAssignableFrom(field.getType())) {
// ...
}
}
}
}
请注意,您也可以通过传入(并存储)TypeToken<V>
的实例来执行此操作 - 如果V
本身是通用类型,这可能会更方便。但是,正如@nickb所说,你实际上需要传入那个实例;你不能依靠泛型来创造它。
另请注意<?>
上的Class<?> aClass
- 此处没有理由使用原始类型。