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