In addition to Jeffreys Response , note that your EdgeCreator interface EdgeCreator no different from Function in its functionality, and createEdges really does not need problematic types of constraints.Thus, one of the solutions is to have EdgeCreator extend Function to simplify createEdges .
import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; public class GenericsBreakJavac8 { public interface Edge<N> { N getNode(); } @FunctionalInterface public interface EdgeCreator<N, E extends Edge<N>> extends Function<N,E> { E createEdge(N node); @Override public default E apply(N t) { return createEdge(t); } } public static <N> List<Edge<N>> createEdges(List<N> nodes) { return createEdges(nodes, DefaultEdge::new); } public static <N> List<Edge<N>> createEdges2(List<N> nodes) { return createEdges(nodes, n -> new DefaultEdge<>(n)); } public static <T,R> List<R> createEdges(List<T> nodes, Function<T,R> edgeCreator) { return nodes.stream().map(edgeCreator).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; } } }
You can also remove the EdgeCreator interface and use Function<N, E extends Edge<N>> in places where forced enforcement is required, but there is no such place in this code. The restriction will continue when someone tries to use createEdges(List,Function) , respectively. its result in a context where a List<Edge<SpecificNodeType>> is required.
Failure to comply with type restrictions over too many code spaces will simply inflate your source code without any benefits.
By the way, in your current code you donβt even need the DefaultEdge class; you can simplify all code to
import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; public class GenericsBreakJavac8 { public interface Edge<N> { N getNode(); } public static <N> List<Edge<N>> createEdges(List<N> nodes) { return createEdges(nodes, n -> () -> n); } public static <T,R> List<R> createEdges(List<T> nodes, Function<T,R> edgeCreator) { return nodes.stream().map(edgeCreator).collect(Collectors.toList()); } }
Holger
source share