Gun*_*hah 2 java java-8 java-stream collectors ecj
我在尝试打印JAVA8收藏家的结果时遇到Ambiguity错误.
我试图打印Product对象中的ID总和的结果,但得到以下错误:
"方法println(double)对于PrintStream类型是不明确的"
这是一小段代码,我收到编译错误:
编辑:添加代码段以获取更多详细信息:
package com.sample.reproduce.bugs;
public class Product {
private double id;
private String productName;
public double getId() {
return id;
}
public void setId(double id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我遇到编译错误的代码行:
System.out.println(productList.stream().collect(Collectors.summingDouble(x -> x.getId())));
Run Code Online (Sandbox Code Playgroud)
班级快照:
如果我将在一个单独的行中使用Collector(println方法之外),我不会收到任何错误.
如果我们在println()方法中使用它,为什么编译器无法检测到JAVA 8收集器的确切返回类型?
使用命令提示符添加另一种方法的细节:
我尝试使用相同JDK版本的命令提示符,并且程序已成功编译和执行.所以Holger的答案似乎是正确的.这似乎仅适用于Eclipse编译器:
这是Eclipse编译器中的一个错误,兔子洞比编译器错误更深.我将你的代码示例缩减为
public static void main(String[] args)
{
println(Stream.of(42).collect(Collectors.summingDouble(d -> d)));
}
public static void println(double x) {}
public static void println(char[] x) {}
public static void println(String x) {}
public static void println(Object x) {}
Run Code Online (Sandbox Code Playgroud)
我只保留了println影响编译器行为的方法.
有方法println(Object x),这是一个应该被调用的一个,因为它是没有装箱操作适用于只有一个,println(double),这是在错误信息和应用后拆箱提到的,并且这两种方法println(char[] x)和println(String x),这是不适用一点都不
拆卸println(double x)方法使错误消失,这是可以理解的,即使错误是不正确的,但是,很奇怪,去掉println(Object x)方法并没有解决这个错误.
而且更糟糕的,去除任何的不适的方法,println(char[] x)或者println(String x),也消除了错误,但生成的代码调用错误的,不适用的方法:
public static void main(String[] args)
{
println(Stream.of(42).collect(Collectors.summingDouble(d -> d)));
}
public static void println(double x) { System.out.println("println(double)"); }
public static void println(char[] x) { System.out.println("println(char[])"); }
//public static void println(String x) { System.out.println("println(String)"); }
public static void println(Object x) { System.out.println("println(Object)"); }
Run Code Online (Sandbox Code Playgroud)
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to [C
at Tmp2.main(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
public static void main(String[] args)
{
println(Stream.of(42).collect(Collectors.summingDouble(d -> d)));
}
public static void println(double x) { System.out.println("println(double)"); }
//public static void println(char[] x) { System.out.println("println(char[])"); }
public static void println(String x) { System.out.println("println(String)"); }
public static void println(Object x) { System.out.println("println(Object)"); }
Run Code Online (Sandbox Code Playgroud)
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String
at Tmp2.main(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
我认为,我们不需要深入了解正式的Java语言规范,将这种行为视为不合适.
同时去除不适用的方法,println(char[] x)并且println(String x),使编译器选择正确的方法,println(Object x)过println(double x),但是这并不令人印象深刻.
作为参考,我测试了版本Oxygen.3a Release(4.7.3a),build 20180405-1200.可能还有其他版本受到影响.