Optional.orElseが匿名型でコンパイルされない


8

私はOptionalと匿名クラスを使用して奇妙な問題に遭遇しました:

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() {
        });
    }
}

最初の2つのメソッドはエラーでコンパイルされません

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

どちらもインターフェースを実装しているため、Bar3つのアプローチすべてが機能することを期待していました。3番目のオプションで問題が修正される理由もわかりません。誰かがこれを説明できますか?


2
のタイプOptional.ofがに固定されてOptional<Bar>いるため、3つ目は問題を修正します。他のすべてのケースでは、それはOptional<SubAnonymousSubclassOfBar>です。しかし、他の2つも適切な共通の上限を型推論すると期待してBarいました。しかし、どうやらOptional<SomeSubclassOfBar>(bar).orElse(someOtherSubclassOfBar)いくつかの手持ちが必要です。
ティロ

回答:


7

タイプウィットネスを使用して、最初の2つのタイプを補足できます。

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

これにより、コンパイラはの戻りを期待していることOptional<Bar>を確認できます。#orElseは、Bar


5

あなたは、そのインターフェースにバーが必要であることをオプションに伝える必要があります。

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

1
ジェネリック医薬品の目的はわかっています。@Thiloが言ったように、javacが型を推測するだろうと思っただけです。
Mirco、

3
うん、Scalaから来たので、これを綴る必要があるのはちょっと不自由だ。一方、javacコンパイルは非常に高速なので、...
Thilo

@Mircoは、 'anon type extensions Bar'を推測します。それがあなたの望んでいないことであるなら、あなたはあなたの意図を述べなければなりません。
Nicktar

5

場合 compiles1

変数が型を持っているので、あなたOptionalは総称型を持ってBarいます。barBar

Foo$1作成した型の匿名クラスはBarスーパー型として持つため、メソッドはコンパイルされます。

場合 doesNotCompile

ここでは、Optionalジェネリック型を持っているFoo$1、あなたはタイプのオブジェクトを渡すためにしようとしているFoo$2orElse持っていないものをFoo$1スーパータイプとして。したがって、コンパイルエラーです。

場合 doesNotCompile2

同様にdoesNotCompileOptionalジェネリック型を持っているFoo$1、あなたは合格しようとしているbar、型の変数BarorElse再び持っていないFoo$1スーパータイプとしては。


これらのエラーを回避する

の呼び出しにタイプウィットネスを追加します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() {
        });
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.