Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics & Polymorphism

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?
like image 602
px5x2 Avatar asked Apr 06 '26 22:04

px5x2


1 Answers

The assignment

Collection<T> myCol = null;
myCol = child.createList();

will fail because you are assigning Collection<ClassChild1> to a Collection parameterized with an unknown type T, which may or may not be ClassChild1.

You have specified T as inferred at the call site, so imagine the following code:

Class1 c1;
Collection<ClassChild2> c = c1.doSth();

You can see that the compiler would paint itself into a corner if it allowed you to compile such a doSth method since inside that method you want to add a ClassChild1 instance to a collection that in this example happens to hold instances of ClassChild2.

like image 70
Marko Topolnik Avatar answered Apr 08 '26 11:04

Marko Topolnik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!