1. 程式人生 > 其它 >Difference between <? extends T> and <? super T> and PECS principle

Difference between <? extends T> and <? super T> and PECS principle

The wildcard(萬用字元) declaration ofList<? extends Number> foo3means that any of these are legal assignments:

List<? extends Number> foo3 = new ArrayList<Number>();  // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>(); // Double extends Number
  1. Reading- Given the above possible assignments, what type of object are you guaranteed to read fromList foo3:

    • You can read aNumberbecause any of the lists that could be assigned tofoo3contain aNumberor a subclass ofNumber
      .
    • You can't read anIntegerbecausefoo3could be pointing at aList<Double>.
    • You can't read aDoublebecausefoo3could be pointing at aList<Integer>.
  2. Writing- Given the above possible assignments, what type of object could you add toList foo3that would be legal forallthe above possibleArrayList

    assignments:

    • You can't add anIntegerbecausefoo3could be pointing at aList<Double>.
    • You can't add aDoublebecausefoo3could be pointing at aList<Integer>.
    • You can't add aNumberbecausefoo3could be pointing at aList<Integer>.

You can't add any object toList<? extends T>because you can't guarantee what kind ofListit is really pointing to, so you can't guarantee that the object is allowed in thatList. The only "guarantee" is that you can only read from it and you'll get aTor subclass ofT.

Now considerList <? super T>.

The wildcard declaration ofList<? super Integer> foo3means that any of these are legal assignments:

List<? super Integer> foo3 = new ArrayList<Integer>();  // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>();   // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>();   // Object is a superclass of Integer
  1. Reading- Given the above possible assignments, what type of object are you guaranteed to receive when you read fromList foo3:

    • You aren't guaranteed anIntegerbecausefoo3could be pointing at aList<Number>orList<Object>.
    • You aren't guaranteed aNumberbecausefoo3could be pointing at aList<Object>.
    • Theonlyguarantee is that you will get an instance of anObjector subclass ofObject(but you don't know what subclass).
  2. Writing- Given the above possible assignments, what type of object could you add toList foo3that would be legal forallthe above possibleArrayListassignments:

    • You can add anIntegerbecause anIntegeris allowed in any of above lists.
    • You can add an instance of a subclass ofIntegerbecause an instance of a subclass ofIntegeris allowed in any of the above lists.
    • You can't add aDoublebecausefoo3could be pointing at anArrayList<Integer>.
    • You can't add aNumberbecausefoo3could be pointing at anArrayList<Integer>.
    • You can't add anObjectbecausefoo3could be pointing at anArrayList<Integer>.

PECS

RememberPECS:"Producer Extends, Consumer Super".

  • "Producer Extends"- If you need aListto produceTvalues (you want to readTs from the list), you need to declare it with? extends T, e.g.List<? extends Integer>. But you cannot add to this list.

  • "Consumer Super"- If you need aListto consumeTvalues (you want to writeTs into the list), you need to declare it with? super T, e.g.List<? super Integer>. But there are no guarantees what type of object you may read from this list.

  • If you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g.List<Integer>.


?是萬用字元 extends T 和 super T 是上邊界(最高的粗略父類)和下邊界(最低的詳細子類)

那麼為什有邊界呢?

因為泛型集合裡物件元素間有繼承關係,但泛型集合裡之間是沒有繼承關係的。

<? extends T>和<? super T>的出現就是為了解決這個問題。

<? extend T >不影響往外取,但不能往裡存。因為編譯器不知道下限,不知道存入規則。

<? super T>不影響往裡存,但取只能放在Object物件裡。因為編譯器不知道上限,所以元素的型別資訊就丟失。