У меня есть фрагмент кода, который компилируется под java 7, но не под java 8. Вот пример самодостаточного воспроизведения (я взял реальный код, который проявляет эту проблему, и пропустил все реализации):
import java.util.Iterator;
class ASTNode<T extends ASTNode> implements Iterable<T> {
@Override public Iterator<T> iterator() { return null; }
}
class List<T extends ASTNode> extends ASTNode<T> {}
interface Function<F, T> {}
class Iterables {
public static <F,T> Iterable<T> transform(
Iterable<F> fromIterable, Function<? super F, ? extends T> function) { return null; }
}
class AstFunctions {
public static <T extends ASTNode<?>> Function<T, String> prettyPrint() { return null; }
}
public class Main {
public static void test() {
List<? extends ASTNode<?>> list = null;
Iterables.transform(list, AstFunctions.prettyPrint());
}
}
Свидетель:
$ javac -version
javac 1.8.0_05
$ javac -source 1.7 Main.java
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
$ javac -source 1.8 Main.java
Main.java:23: error: method transform in class Iterables cannot be applied to given types;
Iterables.transform(list, AstFunctions.prettyPrint());
^
required: Iterable<F>,Function<? super F,? extends T#1>
found: List<CAP#1>,Function<ASTNode<?>,String>
reason: cannot infer type-variable(s) F,T#1,T#2
(argument mismatch; Function<CAP#1,String> cannot be converted to Function<? super CAP#1,? extends String>)
where F,T#1,T#2 are type-variables:
F extends Object declared in method <F,T#1>transform(Iterable<F>,Function<? super F,? extends T#1>)
T#1 extends Object declared in method <F,T#1>transform(Iterable<F>,Function<? super F,? extends T#1>)
T#2 extends ASTNode<?> declared in method <T#2>prettyPrint()
where CAP#1 is a fresh type-variable:
CAP#1 extends ASTNode<?> from capture of ? extends ASTNode<?>
1 error
(Возможно, примечательно, что Eclipse, настроенный для совместимости с 1.8, не имеет проблем с этим кодом).
Является ли это ошибкой компилятора? Если нет, то при допущении, что мне разрешено изменять AstFunctions
и Main
(но не ASTNode
, List
, Function
или Iterables
), как я могу скомпилировать этот код? Я также хотел бы, если возможно, понять, какие изменения в системе типа Java 8 не скомпилируют этот код.