Let\'s say I have two classes and two methods:
class Scratch {
private class A{}
private class B extends A{}
public Optional getItems(List&
Look at this similar example:
Optional optA = Optional.of(new B()); //OK
Optional optB = Optional.of(new B()); //OK
Optional optA2 = optB; //doesn't compile
You can make the second method fail by rewriting it as:
public Optional getItems2(List items) {
return Optional.of(items.stream().map(s -> new B()).findFirst().get());
}
This is simply because generic types are invariant.
Why the difference? See the declaration of Optional.of
:
public static Optional of(T value) {
return new Optional<>(value);
}
The type of the optional is picked up from the target of the assignment (or return type in this case).
And Stream.findFirst()
:
//T comes from Stream, it's not a generic method parameter
Optional findFirst();
In this case, however, return items.stream().map(s -> new B()).findFirst();
doesn't type the result of .findFirst()
based on the declared return type of getItems
(T
is strictly based on the type argument of Stream
)