5

まず、背景を少し説明します (興味がない場合は、少し読み飛ばしてください)。私はイライラして混乱しています!これは非常に単純な使用例であるはずであり、実際、私のコード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/にバグ レポートを投稿しました。承認された場合は、ここにリンクを投稿します。

4

3 に答える 3

2

明らかに、報告する必要があるjavacのバグです。おそらく、開いているjdkメーリングリストの1つで質問するほうが幸運です。しかし、それは感謝祭なので...

これはジェネリックの基本的な使用法ではありませんが、非常に複雑です。

于 2012-11-21T21:29:14.400 に答える
0

試してみませんでしたが、

public class Bug<X extends Property<?, ?> & Anything> {

両方に制限はありません?。次のようなものが必要になります。

public class Bug<C, X extends Property<C, ? extends C> & Anything> {
于 2012-11-21T22:53:41.000 に答える
0

Propertyサンプルを Eclipse Indigo (3.7.1) に入力しましたが、インターフェイスの宣言についてすぐに不平を言いました。

型パラメーター C への不正な前方参照

そして、ラインのためにpublic S get();

戻り型は PropertyConst.get() と互換性がありません

の宣言Propertyをこれに変更

interface Property<C, S extends C > extends PropertyConst<C> {
    @Override
    public S get();
}

両方のエラーを修正し、JDT と Sun の 1.6 コンパイラの両方でコンパイルします

于 2012-11-21T21:05:03.723 に答える