Why does type inference fail here?

kaqqao :

So, I made this relatively simple code, and neither me nor IntelliJ IDEA see anything wrong with it, but javac keels over on the marked line, complaining it can't infer the types:

import java.util.List;
import java.util.stream.Collectors;

public class GenericsBreakJavac8 {

    public interface Edge<N> {
        N getNode();
    }

    @FunctionalInterface
    public interface EdgeCreator<N, E extends Edge<N>> {
        E createEdge(N node);
    }

    public static <N> List<Edge<N>> createEdges(List<N> nodes) {
        return createEdges(nodes, DefaultEdge::new); //the deadly line
    }

    //THE NEWLY ADDED LINE (see the edit note)
    public static <N> List<Edge<N>> createEdges2(List<N> nodes) {
        return createEdges(nodes, n -> new DefaultEdge<N>(n));
    }

    public static <N, E extends Edge<N>> List<E> createEdges(List<N> nodes, EdgeCreator<N, E> edgeCreator) {
        return nodes.stream().map(edgeCreator::createEdge).collect(Collectors.toList());
    }

    public static class DefaultEdge<N> implements Edge<N> {
        private final N node;

        public DefaultEdge(N node) {
            this.node = node;
        }

        @Override
        public N getNode() {
            return node;
        }
    }
}

Splitting the problematic line into 2 with explicit types helps, but the type signature is longer than the lambda, completely defeating the purpose of writing the lambda in the first place...

EDIT: If I use an actual lambda instead of a method reference, I get the problem again. See the newly added method above.

Jeffrey :

javac doesn't like that DefaultEdge is a raw type.

    return createEdges(nodes, DefaultEdge<N>::new);

will work as expected.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=441938&siteId=1