Javaチュートリアルでは、<?>
と<T>
は交換可能であると述べています。[2]行をコンパイルできないのに、なぜ以下の1行目をコンパイルできるのでしょうか。
abstract class A<K extends Number>{
abstract public A<?> f(A<?> k); //[1]
abstract public <S> A<S> f(A<S> k); //[2]
}
Javaチュートリアルでは、<?>
と<T>
は交換可能であると述べています。[2]行をコンパイルできないのに、なぜ以下の1行目をコンパイルできるのでしょうか。
abstract class A<K extends Number>{
abstract public A<?> f(A<?> k); //[1]
abstract public <S> A<S> f(A<S> k); //[2]
}
S
拡張するには制限する必要がありますNumber
:
abstract class A<K extends Number>{
//abstract public A<?> f(A<?> k); //[1]
abstract public <S extends Number> A<S> f(A<S> k); //[2]
}
あなたがそれを使うとき、<?>
それは自動制限されていると思います-本当にわかりません。
何時間も読んで検索した後、私は最終的に自分の質問に対する答えを見つけました。まず第一に、私はについて言わなければなりません<?>
、ここにいくつかの情報があります。
では、あらゆる種類のコレクションのスーパータイプは何ですか?これは、コレクション
<?>
(「不明のコレクション」と発音)、つまり、要素タイプがすべてに一致するコレクションと書かれています。(Javaチュートリアル)
さて、私たちA<?>
はあらゆる種類のAsのスーパータイプです。また、パラメーターA<?>
は任意のAsを(多態的に)引数として受け入れることができるため、1行目がコンパイルされます。
Java仕様は次のことを示しています。
ワイルドカードは、存在型の制限された形式です。ジェネリック型宣言が与えられると、
G<T extends B>
SomeG<?>
にほぼ類似していX<:B
ます。G<X>
Bは境界を表します。X<:B
サブタイプの関係がタイプXとBの間に成り立つことを示します。
したがってA<?>
、実際には自動制限されています;
型引数を宣言するとき<S>
、ある意味でclass S{}
、型SはNumber(私たちの境界)とは関係がなく、1にキャストすると失敗するので、「SextendsNumber」を次のように宣言する必要があります。と同じ効果があり<?>
ます。
これは私にとってはうまくコンパイルされます:
abstract class A<K extends Number>
{
// abstract public A<?> f(A<?> k); //[1]
abstract public A<K> f(A<K> k);
}
?
T
境界がない場合、互換性があります(正確なタイプを失っているので、実際にはそうではありません)。この場合、K
それが拡張する境界がありますNumber
したがって、それをabstract public <S extends Number> A<S> f(A<S> k);
行うには