Optional
sと匿名クラスを使用して奇妙な問題が発生しました:
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>
どちらもBar
インターフェースを実装しているので、3つのアプローチすべてが機能することを期待していました。 3番目のオプションで問題が解決される理由もわかりません。誰かがこれを説明できますか?
タイプウィットネスを使用して、最初の2つのタイプを補足できます。
Optional.<Bar>of(new Bar(){}).orElse(new Bar(){});
これにより、コンパイラーはOptional<Bar>
の戻りを期待していることを確認できます。#orElseは、Bar
の受け入れを推測できます。
あなたは、そのインターフェースにバーが必要であることをオプションに伝える必要があります。
Bar bar = new Bar();
Optional<Bar> o = Optional.of(new Bar() {}).orElse(bar);
compiles1
_変数Optional
の型がBar
であるため、bar
のジェネリック型はBar
です。
作成する_Foo$1
_型の匿名クラスは、スーパータイプとしてBar
を持っているため、メソッドはコンパイルされます。
doesNotCompile
ここでは、Optional
のジェネリック型は_Foo$1
_であり、_Foo$2
_をスーパータイプとして持たないorElse
に_Foo$1
_型のオブジェクトを渡そうとしています。したがって、コンパイルエラーです。
doesNotCompile2
_doesNotCompile
と同様に、Optional
のジェネリック型は_Foo$1
_であり、bar
の型の変数であるBar
をorElse
に渡そうとしていますが、_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() {
});
}
}
_