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

3k Views Asked by At

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

2

There are 2 best solutions below

1
On BEST ANSWER

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.

0
On

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