为什么.forEach(val - > list.add())编译而.forEach(val - > true)不编译?

Leo*_*hko 7 java compiler-errors java-8 java-stream

最好在代码中表达这种行为:

List<Integer> list= new ArrayList<>();
Stream.of(1,2,3).forEach(i -> list.add(1));  // COMPILES

Stream.of(1,2,3).forEach(i -> true);  // DOES NOT COMPILE!
Run Code Online (Sandbox Code Playgroud)

forEach(...)接受Consumer,但为什么第一个例子编译如果List接口有以下签名boolean add(E e)?而第二个收益率:

lambda表达式中的错误返回类型:boolean无法转换为void

Nam*_*man 11

虽然你可能正在寻找

Stream.of(1,2,3).forEach(list::add); // adding all to `list`
Run Code Online (Sandbox Code Playgroud)

为什么第一个例子编译如果List接口有以下签名boolean add(E e)

主要是因为在第一次调用中忽略了该方法的返回类型.这就是它扩展到:

Stream.of(1,2,3).forEach(new Consumer<Integer>() {
    @Override
    public void accept(Integer i) {
        list.add(1); // ignored return type
    }
});  // COMPILES
Run Code Online (Sandbox Code Playgroud)

另一方面,另一个lambda表示更像是a Predicate(也是a FunctionalInterface),表示为true始终从其test方法返回.如果您甚至尝试将其表示为a Consumer,它可能看起来像

Stream.of(1,2,3).forEach(new Consumer<Integer>() {
    @Override
    public void accept(Integer i) {
        return true; // you can correlate easily now why this wouldn't compile 
    }
});  // DOES NOT COMPILE!
Run Code Online (Sandbox Code Playgroud)

通过Brian的评论添加到设计基础

Java允许您调用方法并忽略返回值(方法调用表达式作为语句).由于我们在调用时允许这一点,因此我们在将方法适用于其参数兼容但功能接口为void返回的功能接口时也允许这样做.

编辑:用他自己语言表达,尽可能接近语言规范:

更准确地说,list.add(x)是一个语句表达式,因此是无效兼容的.true不是语句表达式,因此不是void兼容的.forEach(Consumer)需要与 空隙兼容的lambda.

  • 更准确地说,`list.add(x)`是_statement expression_,因此是void兼容的.`true`不是语句表达式,因此不兼容void.`forEach(Consumer)`需要一个与void兼容的lambda. (3认同)

归档时间:

查看次数:

257 次

最近记录:

7 年,5 月 前