尝试打印JAVA8收集器的结果时出现模糊错误

Gunjan Shah 2 java java-8 java-stream collectors ecj

我在尝试打印JAVA8收藏家的结果时遇到Ambiguity错误.

我试图打印Product对象中的ID总和的结果,但得到以下错误:

"方法println(double)对于PrintStream类型是不明确的"

这是一小段代码,我收到编译错误:

编辑:添加代码段以获取更多详细信息:

  1. Product.java域类.

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

}
  1. 我在编译错误的Main.java类:

以下是我遇到编译错误的代码行:

System.out.println(productList.stream().collect(Collectors.summingDouble(x -> x.getId())));

班级快照:

在此输入图像描述

如果我将在一个单独的行中使用Collector(println方法之外),我不会收到任何错误.

如果我们在println()方法中使用它,为什么编译器无法检测到JAVA 8收集器的确切返回类型?

使用命令提示符添加另一种方法的细节:

我尝试使用相同JDK版本的命令提示符,并且程序已成功编译和执行.所以Holger的答案似乎是正确的.这似乎仅适用于Eclipse编译器:

在此输入图像描述

Holger.. 6

这是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) {}

我只保留了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)"); }
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to [C
    at Tmp2.main(Unknown Source)
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)"); }
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String
    at Tmp2.main(Unknown Source)

我认为,我们不需要深入了解正式的Java语言规范,将这种行为视为不合适.

同时去除不适用的方法,println(char[] x)并且println(String x),使编译器选择正确的方法,println(Object x)println(double x),但是这并不令人印象深刻.

作为参考,我测试了版本Oxygen.3a Release(4.7.3a),build 20180405-1200.可能还有其他版本受到影响.

  • @Michael` [C`是`char []`的内部签名.错误消息不会翻译它,请参阅[`Class.getName()`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class html的#的getName()). (2认同)