为什么在 Optional.map(byte[]::clone) 上会出现编译错误?

Why do I get a compile error on Optional.map(byte[]::clone)?

我在 SO 上绝对找不到适合我的问题的答案。 情况:在工作中,我检查了一个现有的 Java8 项目。我使用 Eclipse Neon (4.6.0)

A class 有这个字段:

private final byte[] stream;

class构造函数有这个参数:

byte[] stream

它是这样做的:

    this.stream = Optional.ofNullable(stream)
            .map(byte[]::clone)
            .orElse(ArrayUtils.EMPTY_BYTE_ARRAY);

不幸的是,表达式有一个错误:Type mismatch: cannot convert from Object to byte[] 尤其是 .map(byte[]::clone) 部分 returns 是 Optional<Object>(根据 Eclipse)而不是 Optional<byte[]>.

因为我是唯一一个使用 Eclipse 的人 - 其他人使用 IntelliJ 而且他们没有错误 - 我只能靠自己了。

我做什么can/should(除了按照 Eclipse 的建议在表达式中的某处强制转换为 byte[] 作为快速修复)?

注意:我记得几年前曾在 Java 1.5 泛型中看到过类似的 奇怪 编译错误,但情况恰恰相反:对于我使用的是 Eclipse,但与我一起工作的另一个人使用的是 Netbeans,他遇到了编译错误(经过一番搜索,他发现这是 JDK 中的错误)。

您应该将此报告为 Eclipse 中的错误,因为它使用标准 javac 编译器和其他 IDE 进行编译。具体来说,Eclipse 似乎在 Array Members 的 Java 语言规范部分缺少以下内容:

The members of an array type are all of the following:

  • The public final field length, which contains the number of components of the array. length may be positive or zero.

  • The public method clone, which overrides the method of the same name in class Object and throws no checked exceptions. The return type of the clone method of an array type T[] is T[].

请注意,在 byte[] 中覆盖的 clone 的 return 类型实际上是 byte[],而不是 Object。似乎 Eclipse 编译器将类型推断为 Object.

这绝对是一个 Eclipse 错误。作为解决方法,您可以改用 lambda 表达式:

this.stream = Optional.ofNullable(stream)
        .map(b -> b.clone())
        .orElse(new byte[0]);

它工作正常。