まず、背景を少し説明します (興味がない場合は、少し読み飛ばしてください)。私はイライラして混乱しています!これは非常に単純な使用例であるはずであり、実際、私のコードはEclipse JDT コンパイラーで問題なくコンパイルされているため、これまで確実に実行できるように Maven を構成してきました。Oracle JDK と OpenJDK でコンパイルされないことがあまりにも気になっていて、実際には私のコードに問題があるのではないかと思ったので、もう一度調べてみました。
おそらくバグは、コンパイルを許可するための JDT コンパイラにあり、許可しないための Oracle JDK と OpenJDK ではなく、どちらもこれをテストしたと思いました。問題の元のコードはかなり複雑だったので、問題がどこにあるのかを特定するのははるかに困難でした.
Eclipse JDT コンパイラーまたは Oracle JDK と OpenJDK のいずれかに、かなり重大な (imho) バグがあります。
TL;DR
これは、問題のコードのかなり最小限の表現です。( Anything の型境界は任意のインターフェイスで置き換えることができ、コンパイラの動作は変わりません):
public class Bug<X extends Property<?, ?> & Anything> {
}
interface Property<C, S extends C> extends PropertyConst<C> {
@Override
public S get();
}
interface PropertyConst<C> {
public C get();
}
interface Anything {
}
要約すると、これは問題なくコンパイルできるはずですが、Oracle JDK 7 & 8 と OpenJDK 7 は一致しません。Eclipse Juno を使用してコンパイルします。
上記のコードをこれらのコンパイラのいずれかでコンパイルすると、次のようなエラーが発生しますが、JDT コンパイラでは問題なく動作します。
Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
^
1 error
これは意味がありません。戻り値の型は明らかに関連しています。なぜなら、参照されている 2 つのメソッドのうちの 1 つが必然的に他のメソッドをオーバーライドするからです。私はこれが機能するはずだとほぼ 99% 確信しています。実際、最後の 1% が欠落している唯一の理由は、ジェネリックの使用が基本的すぎて発見されていないためですが、関連するバグレポートは見つかりませんでした。それに。(確かに、 http://bugs.sun.com/は最悪なので、詳しく調べていませんでした。バグ レポートがまだ開いているかどうかで、キーワード検索結果をフィルタリングすることさえできますか? うーん。)
私にとって最も紛らわしい部分は、余分なインターフェイスがエラーとは何の関係もないにもかかわらず、X 上の Anything の型境界を削除すると、問題なくコンパイルされることです。
誰か私の心を休ませてくれませんか? このために存在するバグレポートを知っている人、または以前に経験したことがある人で、何が問題なのか教えてもらえますか? 決定的な回答が得られない場合は、いくつかのバグ レポートを提出します。
編集:
<S extends C, C> で前方参照エラーが発生したと何人かが指摘しました。なぜこのエラーが発生しなかったのかわかりません.JDTを使用してEclipseでコンパイルしました...
とにかく、OpenJDK 7 または Oracle JDK 7/8 ではまだコンパイルできないので、質問を修正して問題を解決しました。
編集2:
簡単なチェックで、この種の前方参照が Java 7 で合法であることが確認されました。
編集3:
http://bugs.sun.com/にバグ レポートを投稿しました。承認された場合は、ここにリンクを投稿します。