Optional.orElse 不使用匿名类型进行编译

Optional.orElse does not compile with anonymous types

我在使用 Optionals 和匿名 类 时遇到了一个奇怪的问题:

public class Foo {
    interface Bar {
    }

    void doesNotCompile() {
        Optional.of(new Bar() {
        }).orElse(new Bar() {
        });
    }

    void doesNotCompile2() {
        final Bar bar = new Bar() {
        };
        Optional.of(new Bar() {
        }).orElse(bar);
    }

    void compiles1() {
        final Bar bar = new Bar() {
        };
        Optional.of(bar).orElse(new Bar() {
        });
    }
}

前两种方法没有编译错误

java: incompatible types: <anonymous test.Foo.Bar> cannot be converted to <anonymous test.Foo.Bar>

我预料到了,因为两者都实现了接口 Bar 所有三种方法都有效。我也无法弄清楚为什么第三个选项可以解决问题。谁能解释一下吗?

您需要告诉 Optional 您想要该界面的 Bar。

Bar bar = new Bar();
Optional<Bar> o = Optional.of(new Bar() {}).orElse(bar);

案例compiles1

您的 Optional 具有通用类型 Bar,因为变量 bar 具有类型 Bar.

您创建的 Foo 类型的匿名 class 具有 Bar 作为超类型,因此该方法可以编译。

案例doesNotCompile

此处,Optional 具有通用类型 Foo,而您正试图将类型 Foo 的对象传递给 orElse,而 orElse 没有 Foo 作为超类型。因此编译错误。

案例doesNotCompile2

doesNotCompile 类似,Optional 具有泛型类型 Foo,您正试图将 bar 类型的变量 Bar 传递给 orElse 又没有 Foo 作为超级类型。


避免这些错误

为您的 Optional::of 调用添加类型见证。这为您的 Optional 提供了通用类型 Bar:

public class Foo {

    interface Bar {
    }

    void doesNotCompile() {
        Optional.<Bar>of(new Bar() {
        }).orElse(new Bar() {
        });
    }

    void doesNotCompile2() {
        final Bar bar = new Bar() {
        };
        Optional.<Bar>of(new Bar() {
        }).orElse(bar);
    }

    void compiles1() {
        final Bar bar = new Bar() {
        };
        Optional.of(bar).orElse(new Bar() {
        });
    }
}

您可以使用类型见证来补充前两个类型:

Optional.<Bar>of(new Bar(){}).orElse(new Bar(){});

这允许编译器看到您期望 Optional<Bar> 的 return,然后#orElse 可以推断出接受任何 Bar