嵌套类不能转换为java.lang.reflect.ParameterizedType

时间:2015-05-15 10:38:30

标签: java generics parameterized-constructor

我正在尝试实现这样的模型结构:

Generic (abstract)
TplInsurance (extends Generic)
TplInsuranceDoctor (nested class in TplInsurance extends TplInsurance)

不幸的是,当我尝试创建TplInsuranceDoctor的对象时,我遇到运行时错误,这是嵌套类:

Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

错误指向Generic contructor:

public Generic() {
    entityClass = ((Class) ((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
}

以下是模型类:

public abstract class Generic<T extends Generic> {
    protected Class<T> entityClass;
    public Generic() {
        entityClass = ((Class) ((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
    }
    public Long id;
}
public class TplInsurance extends GenericDictionary<TplInsurance> {

    public class TplInsuranceDoctor extends TplInsurance {
        public final String color = "success";
        public final String title = "lekarza i dentysty";
    }

这是我创建对象的方式:

TplInsuranceDoctor tDoctor = new TplInsurance().new TplInsuranceDoctor();

我明白我应该以某种方式参数化嵌套类TplInsuranceDoctor的类型,但我不知道如何。我尝试过的所有内容都无法编译。请帮忙

3 个答案:

答案 0 :(得分:2)

如果您在getGenericSuperclass()上调用TplInsuranceDoctor,则会失败,因为其超类是TplInsurance,这不是参数化类型。你必须更进一步才能到达Generic。例如,您可以这样做:

public Generic() {
    Class class1 = getClass();
    Type genericSuperclass = null;
    for(;;) {
        genericSuperclass = class1.getGenericSuperclass();
        if(genericSuperclass instanceof ParameterizedType)
            break;
        class1 = class1.getSuperclass();
    }
    ParameterizedType genericSuperclass_ = (ParameterizedType) genericSuperclass;
    entityClass = ((Class) ((Class) genericSuperclass_.getActualTypeArguments()[0]));
}

此外,如果您删除了与问题无关的所有JPA / Hibernate内容(注释...),那么您的问题会更加清晰。

答案 1 :(得分:1)

虽然接受的答案适用于这个确切的场景,但有许多变化会导致失败。您可以改为查看TypeTools

public Generic() {
    entityClass = TypeResolver.resolveRawClass(Generic.class, getClass());
}

答案 2 :(得分:0)

这是我的工作解决方案。感谢yannick1976

@Transient protected Class<T> entityClass;
public Generic() {
    // for standard class. Dosen't take care of inner/nested classes
    //entityClass = ((Class) ((Class) ((ParameterizedType) (getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
    // works for nested/inner classes
    Class obtainedClass = getClass();
    Type genericSuperclass = null;
    for(;;) {
        genericSuperclass = obtainedClass.getGenericSuperclass();
        if(genericSuperclass instanceof ParameterizedType) {
            break;
        }
        obtainedClass = obtainedClass.getSuperclass();
    }
    ParameterizedType genericSuperclass_ = (ParameterizedType) genericSuperclass;
    entityClass = ((Class) ((Class) genericSuperclass_.getActualTypeArguments()[0]));
}