编译擦除后,生成的类是这样:
  class TObject
  {
  privateObject obj;
  publicvoid Set(Object object)
  {
  this.obj= object;
  }
  }
  首先泛型参数T被向上替换为自身的父类Object,然后将类型参数T去除。
  (3)自定义继承关系泛型类型擦除:
  class Manipulator<Textends SuperClass>
  {
  private T obj;
  public Manipulator(T x){
  obj = x;
  }
  public void doSomething(){
  obj.f();
  System.out.println(obj.getClass().getName());
  }
  }
  首先将泛型参数T向上替换为上边界,然后去除泛型参数:
  class Manipulator
  {
  private SuperClass obj;
  public Manipulator(SuperClass x){
  obj = x;
  }
  public void doSomething(){
  obj.f();
  System.out.println(obj.getClass().getName());
  }
  }
  三、擦除原因:
  泛型不是在java一开始有的,擦除是java中泛型实现的一种折中手段。
  具体来说两个原因使得泛型代码需要类型擦除:
  (1)引入泛型代码不能对现有代码类库产生影响,所以需要将泛型代码擦除为非泛型代码;
  (2)当泛型代码被当做类库使用时,为了兼容性,不需要知道泛型代码是否使用泛型,所以需要擦除;
  5不可协变:
  (1)数组和泛型对比
  数组是可协变的、泛型是不可协变的。
  什么是可协变性?举个例子说明:
  数组可协变(covariant)是指如果类Base是类Sub的基类,那么Base[]是Sub[]的基类。
  泛型不可变的(invariant)是指List<Base>不会是List<Sub>的基类,两者压根没关系。
  (2)泛型为什么不可协变
  泛型“编译时进行类型检查(类型安全)”特性决定了其不可协变。
  ArrayList<Object> objList = new ArrayList<Long>();
  //can't compile pass
  类型安全检查
  Object[] objArray = new Long[10];
  //compile OK
  如果ArrayList<Long>类型对象可以赋值给ArrayList<Object>类型引用,那么违反了泛型类型安全的原则。
  因为如果编译器你这样做,会导致可以往容器中放置非Long型的对象。但是数组无所谓,他不是类型安全的。
  再看看下面代码,第一行编译错误是因为不可协变性,那么为什么第二行可以呢?
  List<Type> listt = new ArrayList<SubType>();
  //can't compile pass
  List<? extends Type> listt = new ArrayList<SubType>();
  //OK
  参考泛型通配符,这是其作用
  不可协变并不代表不能在泛型代码中将父类出现的地方使用子类代替,如下面代码是合法的:
  ArrayList<Type> list = new ArrayList<Type>();
  //Type is SuperClass
  list.add(new SubType());
  //SubType is SubClass
  Type[] tt = new Type[3];
  tt[0] = new SubType();
  (3)数组可协变带来的问题:
  数组的协变性可能会导致一些错误,比如下面的代码:
  public static voidmain(String[] args) {
  Object[] array = new String[10];
  array[0] = 10;
  }
  它是可以编译通过的,因为数组是协变的,Object[]类型的引用可以指向一个String[]类型的对象。但是运行的时候是会报出如下异常的:
  Exception in thread"main" java.lang.ArrayStoreException: java.lang.Integer
  但是对于泛型不会出现这种情况了:
  public static voidmain(String[] args) {
  List< Object> list = newArrayList< String>();
  list.add(10);
  }
  这段代码连编译都不能通过。
  6.通配符:
  通配符在类型系统中的作用部分来自其不会发生协变(covariant)这一特性。即通配符产生一部分原因来自突破不可协变的限制。
  可以认为通配符使得List<?>是List<AnyType>的基类,List<? extends  Type>是List<SubType>的基类。
// collection1可以存放任何类型
Collection<?>collection1 = new ArrayList<String>();
collection1 = newArrayList<Integer>();
collection1 = newArrayList<Object>();
//collection3表示它可以存放Number或Number的子类
Collection<?extends Number> collection3 = null;
collection3 = newArrayList<Number>();
collection3 = newArrayList<Double>();
collection3 = newArrayList<Long>();
//collection4表示它可以存放Integer或Integer的父类
Collection<? superInteger> collection4 = null;
collection4 = newArrayList<Object>();