无法在 JDK 11 中编译方法引用



我目前正在将一个项目迁移到JDK 11并使用Maven编译它。但是,Maven 对单个方法引用提出了一个不稳定的问题(它在其他地方没有问题(。有问题的方法如下所示:

public class MyThing {
    boolean something = true;
    // ...
    public boolean isSomething() {
        return something;
    }
    // ...
}

对上述方法的调用或多或少如下所示:

return methodThatGetsOptionalDefinition(aString)                 // Optional<Definition>
        .map(definition -> defenition.getMyThing(anotherString)) // Optional<MyThing>
        .map(MyThing::isSomething)                               // Optional<Boolean>
        .orElse(true);

编译后,Maven 抛出以下消息:

> mvn clean install -Pdist-snapshot -DskipTests
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project XXXXX: Compilation failure
[ERROR] /D:/XXXXX.java:[63,38] incompatible types: invalid method reference
[ERROR]     method isSomething in class XXXXX.MyThing cannot be applied to given types
[ERROR]       required: no arguments
[ERROR]       found: java.lang.Object
[ERROR]       reason: actual and formal argument lists differ in length
[ERROR]
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.

如果我像这样扩展方法引用,它可以毫无问题地编译:

return methodThatGetsOptionalDefinition(aString)
        .map(definition -> defenition.getMyThing(anotherString))
        .map(myThing -> myThing.isSomething())
        .orElse(true);

键入可选也有效:

return methodThatGetsOptionalDefinition(aString)
        .<MyThing>map(definition -> defenition.getMyThing(anotherString))
        .map(myThing -> myThing.isSomething())
        .orElse(true);

使用 IntelliJ 和 Open JDK 版本 11.0.1 和 11.0.2 编译项目时,也会发生相同的错误。具有讽刺意味的是,IntelliJ抱怨"Lambda可以用方法引用代替"。使用不同的"语言模式"时也会出现此问题。

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>11</source>
        <target>11</target>
    </configuration>
</plugin>

有谁知道为什么会发生这种情况?

一些具体的实现细节已被混淆。

它与 map 方法的类型定义有关。

为了提供方法引用,该方法必须具有匹配的类型定义。流映射有一个函数方法,但你的是一个生产者函数。

Function = (T) -> R
Producer = () -> R

因此,Method::isSomething()与Stream.map不兼容,但您的内联闭包myThing -> myThing.isSomething()是。

相关内容

  • 没有找到相关文章

最新更新