Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics - Cannot convert from <? extends MyObject> to <MyObject> [duplicate]

Tags:

java

generics

Why does the following code give a compile error?

public MyObject(Builder<? extends MyObject> builder) {
    // Type mismatch: cannot convert from MyObject.Builder<capture#5-of ? extends MyObject> to MyObject.Builder<MyObject>
    Builder<MyObject> myObjBuilder = builder;
}

If the Builder type is a subclass of MyObject, then why can't you assign builder to just type MyObject? I need to do this because I am unable to use an object of type MyObject with the builder. Take a look at this code for example:

public MyObject(Builder<? extends MyObject> builder) {
    // The method getData(capture#8-of ? extends MyObject) in the type Builder<capture#8-of ? extends MyObject> is not applicable for the arguments (MyObject)
    this.data = builder.getData(this);
}

I feel like this should be allowed. Or am I missing something here? Is there a way to do this without casting builder to (Builder<MyObject>) and having to use @SuppressWarnings ?

Also note that I need Builder to be <? extends MyObject> because the MyObject and its Builder will be subclassed (as it is abstract).

Thanks for your help!

like image 213
User12345 Avatar asked Jan 24 '15 19:01

User12345


1 Answers

Because Foo<? extends Bar> is not a Foo<Bar>.

Say Foo has a method:

void add (T t)

then by contract, you can only add T objects. Now if T is instantiated as ? extends Bar, we don't know the type. Accepting Bar could lead to problematic behavior: if you have an ArrayList<Foo> you expect the ArrayList to contain only Foo instances. If you would see the ArrayList<Foo> as a ArrayList<SuperFoo>, one can't guarantee that the ArrayList<Foo> contains only Foo's.

Some languages enable covariance: if you only use T as output, you can say that a class Foo<T> is a the same as Foo<SuperT> as well (the same with input). But currently Java doesn't support that. C# however does on the interface level.

like image 112
Willem Van Onsem Avatar answered Sep 27 '22 19:09

Willem Van Onsem