If I have a generic <T2 extends T1>
, does the compiler infer T1 super T2
?
I have a more complex collection, which I reduced to the MWE below. The collection shall be mergeable with any such collection with elements of any subtype.
Now I'm wondering, why the call to forEach
in merge
is not accepted. It fails with
java.util.function.Consumer<java.util.Optional> cannot be converted to java.util.function.Consumer<java.util.Optional<? super T2>>
I've depicted the type relationships in the diagram below. In merge
, T2
extends T1
. The call to forEach
is applied on the other
object, hence the T1
of this
becomes the ?
of other.forEach
and the T2
of this.merge
is the T1
of other
. Hence, this
' T1
should be accepted as super of other
's T1
.
I also tried public void merge(Group<? extends T> other)
with the same result. And public void merge(Group<T> other)
does not accept such collections with elements of any subtype of T1
.
MWE:
class Group<T1> {
public <T2 extends T1> void merge(Group<T2> other) {
Consumer<Optional<T1>> task = t -> t.ifPresentOrElse(this::foo, this::bar);
other.forEach(task);
}
public Collection<Optional<T1>> values() {
return List.of();
}
public void forEach(Consumer<Optional<? super T1>> consumer) {
values().forEach(consumer);
}
private void foo(T1 t) {}
private void bar() {}
}
Relationships:
this.T1 -becomes-> other.forEach.?
^ |
| super
extends |
| v
this.merge.T2 -is-> other.T1
>` is not compatible with `List
– ernest_k Jan 31 '22 at 19:51>`. You may want to try `Consumer super Optional>`, with `task` being declared as `Consumer> task`. There's no reason to make `task` a `Consumer>`