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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With