1

この架空のクラスを考えてみましょう (これはオンライン ビデオで見つけました)。

public class Contrived<T extends Number> extends ArrayList<T> {
      List <? extends T> values;
      ......
    }

Contrivedここで、受け入れることができる型変数はNumberまたは の一部のサブタイプですNumber。ただし、クラス自体は から継承するArrayListため、クラスが取得する型が何であれ、 の型が決まりArrayListます。

というフィールドがありvalues、これはList<? extends T values>です。これはどういう意味ですか?list拡張するものは何でも保持できますかT(これは拡張しますNumber)。

PECS (producer extends, consumer super)原則として、これを使用して要素を読み取ることはできますListが、に追加することはできませんlist

constructorを渡す必要がある場合、どのように見えますlist of doubles or some type Tか?

4

1 に答える 1

2

List<T>またはを取るコンストラクタを使用できますList<? extends T>。クラスを考案し続ける:

class B extends Number{
   public double doubleValue() { return 0; }
   public float floatValue() { return 0; }
   public long longValue() { return 0; }
   public int intValue() { return 0; }
}
class C extends B{}

私は不自然な正当なコンストラクターをContrivedクラスに追加し、次のものを取りますList<? extends T>:

public Contrived(List<? extends T> values)
{
   this.values = values;
}

mainこれにより、次のようなメソッドを書くことができます。

public static void main(String[] args)
{
   List<C> bList = Arrays.asList(new C(), new C(), new C());
   Contrived<B> ci = new Contrived<B>(bList);
}

List<C>aのコンストラクターに a を渡すことができContrived<B>ます。

正当な考案されたコンストラクターの別の設計は、次のようContrivedになりますList<T>

public Contrived(List<T> values)
{
   this.values = values;
}

次の 2 つの例のように、型が一致する必要があるため、このようなコンストラクターは aList<C>に対して a を許可しません。Contrived<B>Contrived

public static void main(String[] args)
{
   List<C> cList = Arrays.asList(new C(), new C(), new C());
   Contrived<C> ci = new Contrived<C>(cList);  // must match now
}

public static void main(String[] args)
{
   List<B> bList = Arrays.asList(new B(), new B(), new B());
   Contrived<B> ci = new Contrived<B>(bList);  // must match now
}
于 2014-02-13T00:23:14.107 に答える