2015-08-08 122 views
4

我正在运行一个小代码来测试Java8 lambda的reduce()功能。 我有一个Person类型的对象列表,其字段为nameage。我试图找到使用Java8的reduce功能的所有人的年龄总和。下面的代码给出:Java8中的Lambda表达式的内部编译器错误

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); 
    } 
} 

当我运行上面的代码,我收到以下错误,虽然我的IDE不显示任何编译错误。

Using javac 1.8.0_25 to compile java sources 
java: An exception has occurred in the compiler (1.8.0_25). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. 
java: java.lang.NullPointerException 
java: at com.sun.tools.javac.code.Types.isConvertible(Types.java:290) 
java: at com.sun.tools.javac.comp.Check.assertConvertible(Check.java:922) 
java: at com.sun.tools.javac.comp.Check.checkMethod(Check.java:876) 
java: at com.sun.tools.javac.comp.Attr.checkMethod(Attr.java:3838) 
java: at com.sun.tools.javac.comp.Attr.checkIdInternal(Attr.java:3615) 
java: at com.sun.tools.javac.comp.Attr.checkMethodIdInternal(Attr.java:3522) 
java: at com.sun.tools.javac.comp.Attr.checkMethodId(Attr.java:3501) 
java: at com.sun.tools.javac.comp.Attr.checkId(Attr.java:3488) 
java: at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3370) 
java: at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1897) 
java: at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607) 
java: at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1843) 
java: at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465) 
java: at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:649) 
java: at com.sun.tools.javac.comp.Attr.visitVarDef(Attr.java:1093) 
java: at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:852) 
java: at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676) 
java: at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:692) 
java: at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1142) 
java: at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909) 
java: at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1035) 
java: at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778) 
java: at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4342) 
java: at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4252) 
java: at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4181) 
java: at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4156) 
java: at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248) 
java: at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901) 
java: at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860) 
java: at com.sun.tools.javac.main.Main.compile(Main.java:523) 
java: at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129) 
java: at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138) 
java: at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:165) 
java: at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:407) 
java: at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:304) 
java: at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:210) 
java: at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:182) 
java: at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1106) 
java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:814) 
java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:862) 
java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:777) 
java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:600) 
java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:352) 
java: at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:184) 
java: at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:129) 
java: at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:224) 
java: at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:113) 
java: at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler$1.run(BuildMain.java:157) 
java: at org.jetbrains.jps.service.impl.SharedThreadPoolImpl$1.run(SharedThreadPoolImpl.java:41) 
java: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
java: at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
java: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
java: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
java: at java.lang.Thread.run(Thread.java:745) 
java: Errors occurred while compiling module 'Lambda' 
Compilation completed with 1 error and 0 warnings in 2 sec 
1 error 
0 warnings 
Error:java: Compilation failed: internal java compiler error 

回答

-1

不错。可能你应该提出一个JDK错误(但首先尝试使用最新版本的代码)。但是代码并没有做你想做的事情。本教程中有一个示例,说明如何正确执行此操作:https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html

在您的代码中result += ...没有意义,因为它是本地参数。而且,我相信编译器努力推断它的类型。

顺便说一句,reduce只有两个参数,你提供三个参数。

+0

减少可以采取三个论据。 U可以在https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#reducing-U-java.util.function.Function-java.util.function中进行验证.BinaryOperator- – Soumya

+0

@Soumya但它将第二个参数作为一个Function,即单个参数lambda,但是您指定了'(result,person)'。你究竟想在这里做什么? – kan

11

这是javac编译器中的已知错误。将编译器更新至版本1.8.0_40(至少)或明确指定lambda参数类型((Integer result, Person person) -> ...)。

+0

这应该是公认的答案! 我有一个类似的错误(编译器错误,但由于AssertionException而不是NPE),并指定参数类型显式修复它。在我的情况下,它是一个类,我只是指定'(Class)c - >'并在执行'Class c - >'修复它。 – jrf

2

虽然Tagir's answer更直接地回答你的问题(关于编译错误),这是值得指出的是,有一个更好的方式来编写你的解决方案,它不仅更干净和更简单的,但不会遇到错误:

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