A DESCRIPTION OF THE PROBLEM :
Under certain conditions, compiler somehow fails to correctly infer type of stream, and defaults to Object.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the enclosed test case and see the compiler to fail.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code compiles.
ACTUAL -
The compiler fails with error:
JavaBug.java:36: error: cannot find symbol
flattened.map(b -> b.intValue());
^
symbol: method intValue()
location: variable b of type Object
suggesting that it failed to infer the type of items in the streams to be of type Number.
---------- BEGIN SOURCE ----------
import java.util.function.Function;
import java.util.stream.Stream;
public class JavaBug {
/**
* This creates stream of streams of mixed types with some base, and flattens it with flatMap(identity).
*
* As long as the stream is stored to variable explicitly typed, everything is good.
*/
public void good1() {
Stream<? extends Number> flattened = Stream.of(Stream.of(1), Stream.of(1L)).flatMap(Function.identity());
flattened.map(b -> b.intValue());
}
/**
* This one uses implicit type of mixed stream, but does not use Function.identity(), it uses explicit lambda instead.
*
* This is good too.
*/
public void good2() {
var flattened = Stream.of(Stream.of(1), Stream.of(1L)).flatMap(x -> x);
flattened.map(b -> b.intValue());
}
/**
* If implicit type of mixed stream is used, and Function.identity is used to flatten the streams, compiler fails.
*/
public void failure() {
var flattened = Stream.of(Stream.of(1), Stream.of(1L)).flatMap(Function.identity());
flattened.map(b -> b.intValue());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
You must either split the pipeline to explicitly name the type of the inferred stream.
Or do not use Function.identity, use explicit lambda instead.
FREQUENCY : always