【发布时间】:2019-02-25 22:50:40
【问题描述】:
我有以下代码编译成功:
import java.lang.String;
import java.util.List;
import java.util.Arrays;
interface Supplier<R> {
Foo<R> get();
}
interface Foo<R> {
public R getBar();
public void init();
}
public class Main {
static private <V> void doSomething(final Supplier<? extends List<? extends V>> supplier) {
// do something
}
static public void main(String[] args) {
doSomething(new Supplier<List<Object>>(){
@Override
public Foo<List<Object>> get() {
return new Foo<List<Object>>(){
@Override
public List<Object> getBar() {
return null;
}
@Override
public void init() {
// initialisation
}
};
}
});
}
}
但是,如果我将 Supplier 转换为以下 lambda 表达式,则代码不再编译:
doSomething(() -> new Foo<List<Object>>(){
@Override
public List<Object> getBar() {
return null;
}
});
编译错误是:
Main.java:22: error: method doSomething in class Main cannot be applied to given types;
doSomething(() -> new Foo<List<Object>>(){
^
required: Supplier<? extends List<? extends V>>
found: ()->new Fo[...]; } }
reason: cannot infer type-variable(s) V
(argument mismatch; bad return type in lambda expression
<anonymous Foo<List<Object>>> cannot be converted to Foo<List<? extends V>>)
where V is a type-variable:
V extends Object declared in method <V>doSomething(Supplier<? extends List<? extends V>>)
如果我将供应商的声明更改为Supplier<? extends List<V>>,则两个变体都编译成功。
我使用 Java 8 编译器编译代码。
为什么带有 lambda 的代码无法编译,虽然它等同于非 lambda 版本? 这是 Java 的已知/预期限制还是错误?
【问题讨论】:
-
在 Java 10 中,它似乎使用菱形运算符
() -> new Foo<>() {...}进行编译(我不确定它是否在 Java 8 上编译,或者它是否符合您的要求)。 -
在 Java 8 中,它不使用菱形运算符进行编译。编译器给了我以下错误:
cannot infer type arguments for Foo<R>
标签: java generics lambda java-8