A bug in the Java 8 compiler.

Andrej Golovnin andrej.golovnin at gmail.com
Wed May 25 08:41:37 UTC 2016


Hi all,

consider following code:

public class Main {

    public static class Details {
        // NOP
    }

    public static class Mapper<T> {

        public T getMapped(String str) {
            return null;
        }

        public List<Details> getDetails(T entity) {
            return Collections.emptyList();
        }

    }

    public static List<Details> calcDetails() {
        Optional<Mapper> opt = Optional.empty();
        return opt.map(m -> getDetails("A", m))
                  .orElseGet(() -> Collections.emptyList());
    }

    private static <E> List<Details> getDetails(String str,
           Mapper<E> mapper)
    {
        E entity = mapper.getMapped(str);
        return mapper.getDetails(entity);
    }

}


When I try to compile it, I get following error message:

Main.java:29: error: incompatible types: Object cannot be converted to
List<Details>
                  .orElseGet(() -> Collections.emptyList());
                            ^
Note: Main.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Neither Eclipse nor Intellij IDEA show an error in the line 29.
The Eclipse Java Compiler is able to compile this code.
And the latest JDK 9 compiler is able to compile this code too.
But the problem is still reproducible in JDK 8u102 Build 04.
It would be nice if you could fix it in JDK 8 too as we hit this problem
multiple times in our project. And I'm sure other developers may hit
this problem too.

Adding a cast fixes the problem for now:

    public static List<Details> calcDetails() {
        Optional<Mapper> opt = Optional.empty();
        return (List<Details>) opt.map(m -> getDetails("A", m))
                  .orElseGet(() -> Collections.emptyList());
    }


Best regards,
Andrej Golovnin


More information about the compiler-dev mailing list