A.2 通用目标类型推断

Java 8对泛型参数的推断进行了增强。相信你对Java 8之前版本中的类型推断已经比较熟悉了。比如,Java中的emptyList方法定义如下:

  1. static <T> List<T> emptyList();

emptyList方法使用了类型参数T进行参数化。你可以像下面这样为该类型参数提供一个显式的类型进行函数调用:

  1. List<Car> cars = Collections.<Car>emptyList();

不过Java也可以推断泛型参数的类型。上述代码和下面这段代码是等价的:

  1. List<Car> cars = Collections.emptyList();

Java 8出现之前,这种推断机制依赖于程序的上下文(即目标类型),具有一定的局限性。比如,下面这种情况就不大可能完成推断:

  1. static void cleanCars(List<Car> cars) {
  2. }
  3. cleanCars(Collections.emptyList());

你会遭遇下面的错误:

  1. cleanCars (java.util.List<Car>)cannot be applied to
  2. (java.util.List<java.lang.Object>)

为了修复这一问题,你只能像之前展示的那样提供一个显式的类型参数。

Java 8中,目标类型包括向方法传递的参数,因此你不再需要提供显式的泛型参数:

  1. List<Car> cleanCars = dirtyCars.stream()
  2. .filter(Car::isClean)
  3. .collect(Collectors.toList());

通过这段代码,我们能很清晰地了解到,正是伴随Java 8而来的改进,你只需要一句Collectors.toList()就能完成期望的工作,不再需要编写像Collectors.toList()这么复杂的代码了。