1

以下のコードを持つ:

    Stack<Integer> integers = new Stack<Integer>();
    Stack<? extends Number> numbers = integers;
    Number n = numbers.pop();
    numbers.push(3);
    numbers.push(n);

最後の 2 行でコンパイル エラーが発生しますが、いくつか考えてみましたが、コンパイル エラーが発生する理由がわかりません。

The method push(capture#2-of ? extends Number) in the type Stack<capture#2-of ? extends Number> is not applicable for the arguments (int)

最後の行にコメントすると、上記のコンパイル エラーが引き続き発生しますが、私の理解では、コンパイラはこれらの行から正しい型 (スタック) を推測できるはずです。

どうもありがとう

4

3 に答える 3

2

最後の 2 行は、任意の数値型numbersのスタックである可能性があるため、有効ではありません。次の同様のコードを検討してください。

Stack<Double> doubles = new Stack<Double>();
Stack<? extends Number> numbers = doubles;
Number n = numbers.pop();
numbers.push(3);
numbers.push(n);

ここで、明らかに正しくない をのInteger上に置こうとしています。Stack<Double>

基本的に、このようなワイルドカードを使用すると、値を出力できますが、値入力することはできません。これは、コンパイラが有効であることを保証できないためです。

于 2011-06-25T07:59:44.543 に答える
2

Java のジェネリック共分散は、クライアントで処理されます。つまり、スタックが共変であると言うセマンティクスがなく、許可している操作 (プッシュなど) が共分散モデルで有効であることをコンパイラーに確認させます。(プッシュはありません)。

ここでの具体的な問題は、次のようなことができるということです。

Number r = new Rational(a,b); // rationals are also numbers
number.push(r);

基になる構造では、これは integer.push(r); を意味します。// 型の不一致

(Programming in Scala の第 19 章には、クライアント側とプロバイダー側​​の (共/対) 分散の非常に明確な説明があります。Scala に詳しくない場合でも読むことをお勧めします)

于 2011-06-25T08:02:45.113 に答える
1

ここで非常に明確な答えは どうすればList <に追加できますか? Number> データ構造を拡張しますか?

于 2011-06-25T07:58:50.123 に答える