简体   繁体   中英

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

I am trying to implement model structure like this:

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

Unfortunatelly I am getting runtime error when I am trying to create object of TplInsuranceDoctor , wich is nested class:

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

That errors points to Generic contructor:

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

Here are model 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";
    }

Here is The way I create object:

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

I understand That I should somehow parametrise type of nested class TplInsuranceDoctor , but I dont know how. Everything I've tried fail compilation. Please help

if you call getGenericSuperclass() on TplInsuranceDoctor , it fails because its superclass is TplInsurance , which is not a parameterized type. You have to go one step further to get to Generic . For example you can do this :

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]));
}

Also, your question would be a lot clearer if you removed all the JPA / Hibernate stuff (annotations...) which really have nothing to do with the problem.

While the accepted answer works for this exact scenario, there are numerous variations that it will fail for. You might check out TypeTools instead:

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

Here is my working solution. Thanks to 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]));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM