Search code examples
javagenericsparameterized-constructor

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


Solution

  • 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.