I had an error while generalizing some classes in order to reduce code duplicates in my project, the case is as follows:
interface ClassRoot{}
public class ClassChild1 implements ClassRoot{
// constructor is omitted for simplicity
public Collection<ClassChild1> createList(){
Collection<ClassChild1> col = getCollectionFromSomewhere();
return col;
}
}
public class Class1{
protected <T extends ClassRoot> Collection<T> doSth(){
Collection<T> myCol = null;
ClassChild1 child = new ClassChild1();
// here I get compile time assignment error
// also (assuming that myCol not null) myCol.add(new ClassChild1());
// is not permitted.
myCol = child.createList();
return myCol;
}
}
Isn’t that against the polymorphism phenomenon? I know that for example,
List<Object> list1;
can never be (and should not be assigned for typesafety) to:
List<String> list2;
But here my case is different, i specified the Type Parameter extending some specific class expecting to make use of OOP Polymorphism concept, and doing assignments right exactly implementing right class.
Now I have 2 questions;
- May someone clearly explain why is that is forbidden in Java, for what justifiable reason?
- How can I implement such a functionality, by using type params or wildcards?
The assignment
will fail because you are assigning
Collection<ClassChild1>to aCollectionparameterized with an unknown typeT, which may or may not beClassChild1.You have specified
Tas inferred at the call site, so imagine the following code:You can see that the compiler would paint itself into a corner if it allowed you to compile such a
doSthmethod since inside that method you want to add aClassChild1instance to a collection that in this example happens to hold instances ofClassChild2.