0

以下のコードについて質問があります。

コンパイラが ty.add(new A()); の受け入れを正確に拒否する理由を教えてください。結局、A は B のスーパークラスです (つまり、要件に対応します)。

エラーメッセージは次のとおりです。

C.java:15: error: no suitable method found for add(A)
                ty.add(new A());
                  ^
    method List.add(int,CAP#1) is not applicable
      (actual and formal argument lists differ in length)
    method List.add(CAP#1) is not applicable
      (actual argument A cannot be converted to CAP#1 by method invocation conversion)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object super: B from capture of ? super B
1 error

そして、ここにコード(C.java)があります:

import java.util.ArrayList;
import java.util.List;

class A
    {
    }
class B extends A
    {
    }
class C extends B
    {
    public static void main(String args[])
        {
        List<? super B> ty = new ArrayList<A>();
        ty.add(new A());
        ty.add(new B());
        ty.add(new C());
        }
    }
4

3 に答える 3

2

あなたは意味を誤解してい? super Bます。これは、コンパイル時に不明なクラス、Bつまり のスーパークラスであることを意味しますB。コンパイラは、Bオブジェクトを追加できることだけを知っていますArrayList<B>。したがって、追加を禁止する必要がありAます。

を追加できるようにするには、またはのタイプをA検討してください。List<? super A>List<A>ty

于 2013-10-10T18:44:35.817 に答える
1

? この場合、普遍的な量指定子ではなく、存在量指定子です。 List< ? super B >として読む必要がありますfor some unknown T such that B <: T, List< T >Bつまり、インスタンス、または逆説的に、インスタンスなどのサブクラスBのみを追加できCます。

于 2013-10-10T19:00:34.823 に答える
1

サブクラス オブジェクトを追加するだけの場合は、リストを次のように宣言します。

List<A> list = new ArrayList<A>();
list.add(new A());  // fine
list.add(new B());  // fine

ArrayList元のリスト宣言の問題は、コンパイラがによって参照されている実際の型がわからないことList<? super B>です。たとえば、すべてのタイプのリストがによってキャプチャ変換可能List<? super B>であると考えてください。

  • List<A>=>AのスーパークラスですB
  • List<B>=>? super BキャプチャできますB
  • List<Object>=>ObjectのスーパークラスですB

したがって、a の追加new A()は 1 番目と 3 番目のリストでは有効かもしれませんが、 では有効ではありませんList<B>。そのため、コンパイラは追加を許可しませんnew A()。ただし、リストを次のように宣言するList<? super A>とうまくいきます。しかし、ここでも を使用List<A>してください。それがここで必要なことです。

List<? extends X>-or のようなリストを作成することの要点は、List<? super X>さまざまな具体的なパラメーター化されたインスタンス化をList<E>単一の参照にバインドできるようにすることです。


参考文献:

于 2013-10-10T18:47:48.510 に答える