The following classes and methods:
class A<T extends B> { }
class B {}
Stream<A<? extends B>> find() {
return findAll() // Stream<Optional<A<? extends B>>>
.filter(Optional::isPresent) // Stream<Optional<A<? extends B>>>
.map(Optional::get) // Stream<A<capture of ? extends B>>
.filter(a -> false); // Stream<A<capture of ? extends B>>
}
Stream<Optional<A<? extends B>>> findAll() {
return Stream.empty();
}
Compile fine with javac, but lead to type errors in IDEA:
The errors disappear when I either
- Remove the
filter(Optional::isPresent()).map(Optional::get)
pair - Remove the ultimate
filter
call
I can't make any sense of that. Is it an IDEA bug?
Edit: Some new insights thanks to LuCio :
While my version of javac (10.0.2) does not complain, other javac versions and IDEs do, so it's not an IDEA bug
Splitting the expression in two and giving the intermediate value an explicit type helps:
Stream<A<? extends B>> aStream = findAll() .filter(Optional::isPresent) .map(Optional::get); return aStream .filter(a -> false);
(note that the type IDEA infers for
aStream
isStream<? extends A<? extends B>>
, although it just accepts the assignment to this type)
So the question becomes: Why is the intermediate type the way it is, and why is it apparently OK to just ignore it by assigning to another type?