Java Generics

Generic Method

  1. 如果可以使用泛型方法来替代整个类的泛型化就应该使用泛型方法
  2. static方法无法访问泛型类的类型参数,所有static方法需要使用泛型能力就必须称为泛型方法
    public class GenericMethods{
        public <T> void f(T x){
            System.out.println(x.getClass().getName());
        }
    }

使用泛型方法时不必知名参数类型,因为编译器会找出具体类型 – type argument inference

Generic Type and Wildcard <?>

  1. 用来声明一个泛型方法或者泛型类。
  2. 通配符<?> 使用泛型类或者泛型方法

Type Erasure

考虑下面的情况,返回的结果为true。

    public class ErasedTypeEquivalence{
        public static void main(String[] args){
            Class c1 = new ArrayList<String>().getClass();
            Class c2 = new ArrayList<Integer>().getClass();
            System.out.println(c1 == c2); //true
        }
    }

在泛型代码内部,无法获得任何有关泛型类型参数类型的信息

  Map<Long, Double> p = new HashMap<>();
  System.out.println(p.getClass().getTypeParameters); //[K, V]

如下代码不能编译

  public class HasF {
      public void f() { System.out.println("HasF.f()"); }
  }

  class Manipulator<T> {
      private T obj;
      public Manipulator (T x) { obj = x; }
      public void manipulate() { obj.f(); } //compilation error
  }

  public class Manipulation {
      public static void main(String[] args) {
          HasF hf = new HasF();
          Manipulator<HasF> manipulator = new Manipulator<>();
          manipulator.manipulate();
      }
  }

由于擦除机制,Java编译器无法将manipulate()方法在obj上调用f()与HasF拥有f()这一事实映射起来

修改Manipulator类为,泛型擦除会将类擦除到第一边界HasF

  class Manipulator<T extends HasF>

泛型擦除机制的引入是为了兼容Java SE5之前的代码