11

このコードが正常にコンパイルされるのはなぜでしょうか?

ソースコード:

abstract class A<K extends Number>
{
    public abstract <M> A<? super M> useMe(A<? super M> k);
}

正常にコンパイルされました

どのように機能し、なぜこれがコンパイルされるのですか? M は任意の型であるのに、なぜ使用できるのでしょうか。次のようにする必要があります<M extends Number>。これはコンパイルされません:

abstract class A<K extends Number>
{
    public abstract <M> A<? super M> useMe(A<M> k);
}

エラーメッセージ:

型引数 M は型変数 K の境界内にありません。ここで、M、K は型変数です: M extends メソッド useMe(A) で宣言された Object K extends クラス A で宣言された Number

違いはなんですか?

4

4 に答える 4

5

このコンパイラの動作は、この Eclipse バグで議論されました。もともと、Eclipseコンパイラはあなたの例の式に対してエラーを出しましたが、javacはそうではありませんでした。私はまだ JLS を直接検索していませんが、コンセンサスは、型パラメーターの境界に対して下限のワイルドカードをチェックする必要がある仕様には何もないようです。この状況では、制約を満たす型を割り当てることは最終的に呼び出し元に委ねられます (その投稿で Stephan Herrmann が推測したように)。

于 2013-12-24T00:13:24.883 に答える
2

これは驚くほど無意味なコードです。

それが言っているのは、クラスAが a であるジェネリック型Kを取り、(明らかに a である以外に)無意味な追加の制限を伴うan を返すNumberメソッドがあるということだけです。useMeA<T>TNumber

これは、砂糖によってほとんど言われていないことを示す実装です。

abstract class A<K extends Number> {
    public abstract <M> A<? super M> useMe(A<? super M> k);
}

class B extends A<Number> {

    @Override
    public <M> A<? super M> useMe(A<? super M> k) {
        // Not much more you can do here but this.
        return k;
    }

}

意味の? super Mないゴブルデグクです-コンパイラがそれから導き出せるのは、渡されたパラメータと返された結果の両方が特定の名前のないクラスのスーパークラスでなければならないということだけです。

ジェネリックは、コンパイル時にコーディング ミスを簡単に検出できるようにするために存在します。このような巨大なジャンボを使用することは、誤解を招く難読化です。

于 2013-12-24T00:11:34.293 に答える
1

最初の例に追加<M extends Number>しても、コンパイラが気にするものは何も追加されません。「M は Number のサブタイプである」および「型は M のスーパータイプである」と言っている場合、「M のスーパータイプである型」と言っていることに注意してください。番号。

より良い例として、MbeIntegerと変数 be の型を指定しA<Object>ます。明らかにそれは機能しませんが、関数のすべての要件を正しく満たしています。

関数定義を修正する方法がないため、関数定義を通過させ、呼び出しサイトが問題をキャッチすると想定します。

于 2013-12-23T23:36:55.580 に答える
-1

あなたの質問には2つの部分があります:

パート 1: とは<M>?

メソッドにジェネリック パラメーターが存在すると、そのメソッドは "型付きメソッド" になります。つまり、メソッドには、通常は推論によって、呼び出し元によって決定されるジェネリック型があります。制限される場合があります。クラスにも型があり、メソッドがインスタンス メソッドである場合、2 つの型は無関係です。

パート2:

ジェネリック型は正確に一致する必要があります。その理由は、 が のサブタイプである場合、Bは のサブタイプではない、より具体的には のサブタイプASomeClass<T extends B>はないという事実に要約されます。SomeClass<T extends A>SomeClass<A>SomeClass<? super A>

于 2013-12-24T05:28:46.320 に答える