(1) 如何创建泛型方法

  我们用例子来说明一下如何创建一个泛型方法:

  

  public static List toList(T[] arr) {

  List lists = new ArrayList();

  for(T element : arr) {

  lists.add(element);

  }

  return lists;

  }

  }

  我们可以这样进行调用

  List ints = Lists.toList(new Integer[]{1, 2, 3});

  List words = Lists.toList(new String[]{“a”, “b”, “c”});

  上面例子的方法签名的第一个,初看起来比较奇怪,和我们传统的方法签名并不相同,这个表示为我们的方法声明一个类型变量(type variable),该类型变量被应用于方法签名及方法体,这个类型变量的作用域仅限于该方法本身。

  (2) vararg(动态参数)的应用

  将参数打包成一个数组传入方法中是一件让人讨厌的事,在jdk1.5中加入了一个新的功能称为vararg(动态参数),让我们来看看示例

  

  public static List toList(T… arr) {

  List lists = new ArrayList();

  for(T element : arr) {

  lists.add(element);

  }

  return lists;

  }

  }

  Lists ints = Lists.toList(1,2,3);

  我们看到”…”就表示方法接受动态参数,其实在运行时的时候,调用方法的参数,也是被打包成一个数组传入,只不过这一次是jvm帮我们做了。

所以我们也可以采用以下的方法进行调用:

  

      Lists ints = Lists.toList(new Integer[]{1,2,3});

  不过在使用vararg功能时,需要留意的是,当方法中待传入的参数除了动态参数外,还有其它参数,则必须将动态参数方法在参数列表的最后面,例如:

  

      public static void addAll(List list, T… arr);

  

(3) 调用泛型方法时显式给定类型参数的问题

  我们在调用泛型方法时,还有一个要注意的地方是,是否在调用时显式地写明类型参数(type parameter),例如:

  < 1>List< Integer> ints = Lists< Integer>.toList();

  < 2>List< Object> objs = Lists< Object>.toList(1, “abc”);

  一般的情况下,其实都不需要显式地指明类型参数,但对于上面的两种情况,可能就非常有必要。

  上面的< 1>式,我们没有传入任何参数,这样的话,类型推断算法就无法确定在方法内部的类型是什么了。

  上面的< 2>式,我们第一个参数传入整数,第二个参数传入字符串,你可能会认为,类型推断算法应该会推断出Integer及String的基类是Object,但是Integer及String,同时实现了Serializable和Comparable接口,这样类型推断算法就不能在这三者中作出正确的选择了。