5

私がこれを持っているとしましょう:

class Base<T> {}

class Derived<T> extends Base<T> {}

次に、私のコードでは、次のような警告なしで安全にキャストできます。

public <T> void foo(Base<T> base) {
    Derived<T> f = (Derived<T>) base; // fine, no warning
}

これは問題ありません。ただし、派生クラスにさらに多くの型パラメーターがある場合、それは機能しなくなります。

class Base<T> {}

class Derived<T, U> extends Base<T> {}

public <T> void foo(Base<T> base) {
    Derived<T, ?> f = (Derived<T, ?>) base; // unchecked warning!
}

何故ですか?ここで私が見逃している明らかなものはありますか?

4

1 に答える 1

5

これは私にはバグのようです。JLS §5.5.2 よりチェックされたキャストとチェックされていないキャスト:

型 S からパラメーター化された型 (§4.5) T へのキャストは、次の条件の少なくとも 1 つが保持されない限りチェックされません。

  • S <: T

  • T のすべての型引数 (§4.5.1) は無制限のワイルドカードです

  • T <: S および S には、X の型引数が T の型引数に含まれていない T 以外のサブタイプ X はありません。

Base<T>あなたのタイプとDerived<T, ?>asSとそれぞれを考えるとT、最初の 2 つの条件は明らかに当てはまりません。

の型引数に型引数が含まれていないBase<T>以外のサブタイプを識別できる場合、3 番目の条件が残ります。警告が正しければ、そのようなサブタイプが存在するはずですが、特定できません。たとえば、 のサブタイプではないため、 は機能しません。Derived<T, ?>Derived<T, ?>Derived<?, ?>Base<T>

于 2013-07-26T14:58:53.820 に答える