嵌套 class 无法转换为 java.lang.reflect.ParameterizedType

Nested class cannot be cast to java.lang.reflect.ParameterizedType

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

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

不幸的是,当我尝试创建嵌套 class:

TplInsuranceDoctor 对象时出现运行时错误
Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

错误指向通用构造函数:

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

这里是模型 classes:

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();

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

如果您在 TplInsuranceDoctor 上调用 getGenericSuperclass(),它会失败,因为它的超类是 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 内容(注释...),您的问题会更清楚。

这是我的工作解决方案。感谢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]));
}

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

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