Java8中Lambda表达式的内部编译器错误

Java8中Lambda表达式的内部编译器错误,java,java-8,javac,Java,Java 8,Javac,我正在运行一个小代码来测试Java8 lambda的reduce()功能。 我有一个Person类型的对象列表,其中包含name和age字段。我正在尝试使用Java8的reduce功能查找所有人的年龄总和。代码如下: public class Person { String name; Integer age; public Person(String name, Integer age) { this.name = name; thi

我正在运行一个小代码来测试Java8 lambda的
reduce()
功能。 我有一个
Person
类型的对象列表,其中包含
name
age
字段。我正在尝试使用Java8的reduce功能查找所有人的年龄总和。代码如下:

public class Person {

    String name;
    Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


public class TestReduce {
    public static void main(String[] args){
       Person p1 = new Person("P1", 10);
       Person p2 = new Person("P2", 20);
       Person p3 = new Person("P3", 30);

       List<Person> personList = new ArrayList<Person>();
       personList.add(p1);
       personList.add(p2);
       personList.add(p3);

       int sumAge = personList.stream()
                       .reduce(0, (result, person) -> result += person.age, Integer::sum);
    }
}

很好。可能您应该引发一个JDK错误(但是首先尝试使用最新版本的代码)。但是代码并没有执行您试图执行的操作。本教程提供了一个如何正确操作的示例:

在代码中,
result+=…
没有意义,因为它是一个局部参数。而且,我相信编译器很难推断出它的类型


顺便说一句,
reduce
只接受两个参数,您提供了三个。

这是javac编译器中已知的错误。将编译器更新至1.8.0_40版本(至少)或明确指定lambda参数类型(
(整数结果,个人)->…
)。

尽管更直接地回答了您的问题(关于编译器错误),值得指出的是,有一种更好的方法来编写您的解决方案,它不仅更干净、更简单,而且不会遇到这种错误:

int sumAge = personList.stream().mapToInt(Person::age).sum();

reduce可以包含三个参数。您可以在@Soumya中验证它,但它将第二个参数作为函数,即单个参数lambda,但您指定的是
(result,person)
。你到底想干什么?这应该是公认的答案!我有一个类似的错误(编译器错误,但由于AssertionException而不是NPE),并明确指定参数类型修复了它。在我的例子中,它是一个类,我只是指定
(Class)c->
,然后执行
类c->
修复了它。
int sumAge = personList.stream().mapToInt(Person::age).sum();