Skip to content
Advertisement

ClassCastException “Parent cannot be cast to class…are in unnamed module of loader ‘app’ ” with Java Generics and inheritance

I´m currently facing a problem with generics in Java. I need to return a parent instance casted to the child.

The sample below shows what I´m trying to achieve.

public class GenericTest {

    @Test
    public void test() {
        assertEquals("child", new B().returnParentInstanceAsChild().name());
    }

    public static class Parent {
        public String name() {
            return "parent";
        }
    }

    public static abstract class A<Child extends Parent> {
        public Child returnParentInstanceAsChild() {
            return (Child) new Parent();
        }
    }

    public static class ChildEntity extends Parent {
        @Override
        public String name() {
            return "child";
        }
    }

    public static class B extends A<ChildEntity> {
    }

}

This code does not run through and produces this exception instead:

class com.generics.GenericTest$Parent cannot be cast to class com.generics.GenericTest$ChildEntity (com.generics.GenericTest$Parent and com.generics.GenericTest$ChildEntity are in unnamed module of loader ‘app’) java.lang.ClassCastException: class com.generics.GenericTest$Parent cannot be cast to class com.generics.GenericTest$ChildEntity (com.generics.GenericTest$Parent and com.generics.GenericTest$ChildEntity are in unnamed module of loader ‘app’)

I´m wondering why it fails, as we have enforced that Child needs to be of type Parent.

Why is there a problem and how can it be solved?

Advertisement

Answer

This fails for the same reason the below line fails:

ChildEntity child = (ChildEntity) new Parent();

At runtime the cast will fail because a Parent is not a ChildEntity.

You probably want to make the subclass responsible for creating the child instance, so you can make the parent class method abstract:

public static abstract class A<T extends Parent> {
    public abstract T returnParentInstanceAsChild();
}

public static class B extends A<ChildEntity> {

    @Override
    public ChildEntity returnParentInstanceAsChild() {
        return new ChildEntity();
    }
}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement