我有以下课程:
public abstract class ClassWithHelper<T extends HelperInterface> {
Class<T> helperClass;
protected T helper;
protected Gson gson = new GsonBuilder().create();
public void loadHelper(String helperString) throws InstantiationException, IllegalAccessException {
if (!Strings.isNullOrEmpty(helperString)) {
wizard = gson.fromJson(helperString, getHelperClass());
} else {
wizard = getHelperClass().newInstance();
}
}
protected abstract Class<T> getHelperClass();
}
public class ImplementingClass extends ClassWithHelper<HelperClass> {
@Override
protected Class<HelperClass> getHelperClass() {
return HelperClass.class;
}
}
现在,最好的是当我调用implementClass.helperClass时,它会自动将它强制转换为HelperClass。但是,我想知道我是否真的需要编写和覆盖getHelperClass。我不能写helper.getClass(因为它可能是null),我知道我写它的方式是类型擦除问题。
但是,有没有办法让我重写我的代码以避免必须以两种方式声明helperClass并且仍然有类型推断呢?
答案 0 :(得分:3)
试试这个:
protected Class<T> getHelperClass() {
final ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
return (Class<T>) parameterizedType.getActualTypeArguments()[0];
}
答案 1 :(得分:1)
Afaik,除非你能反思helper
,否则遗憾的是没有运行时类型信息 - 泛型严格是一个编译时工具。
有不同的方法可以做到这一点 - 将类型作为参数包含在ClassWithHelper的构造函数中而不是覆盖方法,或强制子类型提供helperFromJSON
和newHelper
方法 - 如果您认为看起来更好,但如果您需要在运行时使用该类型,则需要“以两种方式说明”。
答案 2 :(得分:1)
这个怎么样:
public abstract class ClassWithHelper<T extends HelperInterface> {
Class<T> helperClass;
protected T helper;
protected Gson gson = new GsonBuilder().create();
public void loadHelper(String helperString) throws InstantiationException, IllegalAccessException {
if (!Strings.isNullOrEmpty(helperString)) {
wizard = gson.fromJson(helperString, getHelperClass());
} else {
wizard = getHelperClass().newInstance();
}
}
public Class<T> getHelperClass() {
return helperClass;
}
protected ClassWithHelper(Class<T> helperClass) {
this.helperClass = helperClass;
}
}
public class ImplementingClass extends ClassWithHelper<HelperClass> {
public ImplementingClass() {
super(HelperClass.class);
}
}