造成flist的add()完全不可用的原因是,在这种情况下add()的参数也变成了“? extends Fruit”。下面这个例子可以帮助你进行理解:
  //: generics/Holder.java
  public class Holder<T> {
  private T value;
  public Holder() {}
  public Holder(T val) { value = val; }
  public void set(T val) { value = val; }
  public T get() { return value; }
  public boolean equals(Object obj) {
  return value.equals(obj);
  }
  public static void main(String[] args) {
  Holder<Apple> Apple = new Holder<Apple>(new Apple());
  Apple d = Apple.get();
  Apple.set(d);
  // Holder<Fruit> Fruit = Apple; // Cannot upcast
  Holder<? extends Fruit> fruit = Apple; // OK
  Fruit p = fruit.get();
  d = (Apple)fruit.get(); // Returns ‘Object’
  try {
  Orange c = (Orange)fruit.get(); // No warning
  } catch(Exception e) {
  System.out.println(e);
  }
  // fruit.set(new Apple()); // Cannot call set()
  // fruit.set(new Fruit()); // Cannot call set()
  System.out.println(fruit.equals(d)); // OK
  }
  } /* Output: (Sample)
  java.lang.ClassCastException: Apple cannot be cast to Orange
  true
  *///:~
  同样的道理,对于上例中的fruit来说,其set()方法的参数变成了“? extends Fruit”,这意味着其接受的参数可以是 任意类型,只需满足上界为Fruit 即可,而编译器无法验证“任意类型”的类型安全性。
  反过来看看指定下界的效果:
  //: generics/SuperTypeWildcards.java
  import java.util.*;
  class Jonathan extends Apple {}
  public class SuperTypeWildcards {
  static void writeTo(List<? super Apple> apples) {
  apples.add(new Apple());
  apples.add(new Jonathan());
  // apples.add(new Fruit()); // Error
  }
  } ///:~
  可以看到,写入操作变得合法。显然,Apple类型满足下界需求,执行写入操作没有安全性问题,而Jonathan是Apple的子类,经过向上转型,也可以符合需求,而Apple的基类Fruit则仍然由于类型不定而被拒绝。
  基本类型不能作为类型参数
  不能创建List<int>之类,而需使用List<Integer>,但因为自动包装机制的存在,所以写入数据时可以使用基本数据类型。
  实现参数化接口
  一个类不能实现同一个泛型接口的两种变体,因为擦除会让它们变成相同的接口:
  //: generics/MultipleInterfaceVariants.java
  // {CompileTimeError} (Won’t compile)
  interface Payable<T> {}
  class Employee implements Payable<Employee> {}
  class Hourly extends Employee
  implements Payable<Hourly> {} ///:~
  Hourly不能编译。但是,如果从Payable的两种用法中移除掉泛型参数(像编译器在擦除阶段做的那样),这段代码将能够编译。
  重载
  以下代码无法编译,因为擦除会让两个方法产生相同的签名:
  //: generics/UseList.java
  // {CompileTimeError} (Won’t compile)
  import java.util.*;
  public class UseList<W,T> {
  void f(List<T> v) {}
  void f(List<W> v) {}
  } ///:~
  自限定类型
  class SelfBounded<T extends SelfBounded<T>> { // ...