1.泛型语法:
  泛型类: class ClassName<T>{}
  泛型方法:public <T> void f(T x){}
  基本指导原则:如果使用泛型方法可以取代将整个类泛型化,那么应该使用泛型方法,因为它可以让事情更加清楚。
  2.为什么使用泛型?
  在Java SE1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
  泛型的好处是:
  (1)在编译时检查类型安全;
  (2)并且所有的强制转换都是自动和隐式的,提高代码的重用率。
  促成泛型出现引人注目的一个原因是为了创造容器类。
  优先考虑泛型!!!
  使用泛型比使用需要在客户端代码中进行转换的类型来的更加安全,也更加容易。
  在设计新类型的时候,要确保它们不需要这种转换可以使用。这通常意味着要把类做成是泛型的。
  比如
  客户端代码使用Stack的时候,如果不使用泛型,在取用Stack中的对象时还需要进行不安全的类型判断,类型转换等,而且代码还比较复杂。如果使用带泛型的Stack,客户端代码中不需要进行类型转换了,直接使用而且不会复杂。
  3.泛型数组:
  无法创建泛型数组,一般的解决方式是在任何想要使用泛型数组的地方使用ArrayList。
  public <T> voidtest()
  {
  //Cannotcreate a generic array of T
  T[]tList = new T[10];
  int[]iList = new int[10];
  //useArrayList<T>
  ArrayList<T>sList = new ArrayList<T>();
  }
  4.类型擦除:
  一、概念
  类型擦除:将泛型类型中类型参数信息去除,只映射为一份字节码,在必要时进行类型检查和类型转换。
  编译时通过两个步骤来对泛型类型的类型进行擦除:
  1.将所有的泛型参数用其左边界(的父类型)类型替换。
  2.移除所有的类型参数。
  备注:擦除也是为什么泛型必须编译时进行类型检查的原因,因为运行时类型信息被擦除了。
  二、擦除举例
  (1)容器泛型类型擦除:
ArrayList<Integer>l1 = new ArrayList<Integer>();
ArrayList<String> l2= new ArrayList<String>();
LinkedList<Integer>l3 = new LinkedList<Integer>();
List<String> l4 =new LinkedList<String>();
System.out.println(l1.getClass().getName());
System.out.println(l2.getClass().getName());
System.out.println(l3.getClass().getName());
System.out.println(l4.getClass().getName());
//output
java.util.ArrayList
java.util.ArrayList
java.util.LinkedList
java.util.LinkedList
  可以看到上面四个泛型类型的类型信息均被擦出掉了,比如ArrayList<Integer>和ArrayList<String>编译后生成的字节码是一份。
  (2)自定义泛型类型擦除:
  再看一个自定义的泛型类:
  class TObject<T>
  {
  privateT obj;
  publicvoid Set(T object)
  {
  this.obj= object;
  System.out.println("T:"+object.getClass().getName());
  }
  }