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]
} 
4

4 に答える 4

3

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]
}

あなたがそれを使うとき、<?>それは自動制限されていると思います-本当にわかりません。

于 2012-11-24T20:52:02.320 に答える
1

何時間も読んで検索した後、私は最終的に自分の質問に対する答えを見つけました。まず第一に、私はについて言わなければなりません<?>、ここにいくつかの情報があります。

では、あらゆる種類のコレクションのスーパータイプは何ですか?これは、コレクション<?>(「不明のコレクション」と発音)、つまり、要素タイプがすべてに一致するコレクションと書かれています。(Javaチュートリアル

さて、私たちA<?>あらゆる種類のAsのスーパータイプです。また、パラメーターA<?>は任意のAsを(多態的に)引数として受け入れることができるため、1行目がコンパイルされます。 Javaチュートリアル

Java仕様は次のことを示しています。

ワイルドカードは、存在型の制限された形式です。ジェネリック型宣言が与えられると、G<T extends B>SomeG<?>にほぼ類似していX<:Bます。G<X>

Bは境界を表します。X<:Bサブタイプの関係がタイプXとBの間に成り立つことを示します。

したがってA<?>、実際には自動制限されています;

型引数を宣言するとき<S>、ある意味でclass S{}、型SはNumber(私たちの境界)とは関係がなく、1にキャストすると失敗するので、「SextendsNumber」を次のように宣言する必要があります。と同じ効果があり<?>ます。

于 2012-12-12T07:39:08.413 に答える
0

これは私にとってはうまくコンパイルされます:

abstract class A<K extends Number>
{
//  abstract public A<?> f(A<?> k); //[1] 
    abstract public A<K> f(A<K> k); 
} 
于 2012-11-24T20:50:50.417 に答える
0

?T境界がない場合、互換性があります(正確なタイプを失っているので、実際にはそうではありません)。この場合、Kそれが拡張する境界がありますNumber

したがって、それをabstract public <S extends Number> A<S> f(A<S> k);行うには

于 2012-11-24T20:48:16.763 に答える