Let's say I have an interface Bar and an implementing class Foo:
interface Bar { ... }
class Foo implements Bar {
static final Foo X = new Foo();
static final Foo Y = new Foo();
static final Foo[] FOOS = { X, Y };
}
Now let's say I have a class with methods that return Optional<Bar>:
public class Fubar {
public Optional<Bar> fromValue() {
return Optional.of(Foo.X); // This is fine
}
public Optional<Bar> fromStreamA() {
Optional<Foo> foo = Arrays.asList(Foo.FOOS).stream().findFirst();
return foo; // This fails to compile
}
public Optional<Bar> fromStreamB() {
Optional<Foo> foo = Arrays.asList(Foo.FOOS).stream().findFirst();
if (foo.isPresent()) {
return Optional.of(foo.get()); // This is also fine
}
return Optional.empty();
}
}
The method fromValue() compiles correctly, however fromStreamA() does not. I get an error message along the lines of Type mismatch: cannot convert from Optional<Foo> to Optional<Bar>. I worked around this mismatch in fromStreamB() (which compiles correctly).
I'm having trouble understanding why fromStreamA() does not compile. I sense it's something to do with generics and is similar to why List<Foo> cannot be assigned to List<Bar>, however I can't grasp it. Can anyone explain why fromValue() is fine and fromStreamA() is not.