Java 8新特性 - (7)泛型的类型推断

分享到:

文章目录

泛型简介

泛型由Java 1.5引入,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。通俗点将就是“类型的变量”。这种类型变量可以用在类、接口和方法的创建中。理解Java泛型最简单的方法是把它看成一种便捷语法,能节省某些Java类型转换(casting)上的操作.

泛型的最大优点是提供了程序的类型安全同时可以向后兼容,但也有尴尬的地方,就是每次定义时都要写明泛型的类型,这样显示指定不仅感觉有些冗长。Java 7中对泛型做了改进,编译器会根据变量声明时的泛型类型自动推断.

1// Java 7之前的写法
2Map<String, String> myMap = new HashMap<String, String>();
3
4// Java 7及之后的写法
5Map<String, String> myMap = new HashMap<>(); //注意后面的"<>"

但是,Java 7在创建泛型实例时的类型推断是有限制的:只有构造器的参数化类型在上下文中被显著的声明了,才可以使用类型推断,否则不行。例如:下面的例子在java 7无法正确编译(但在java8里面可以编译,因为根据方法参数来自动推断泛型的类型):

1List<String> list = new ArrayList<>();
2list.add("A");
3// 由于addAll期望获得Collection<? extends String>类型的参数,因此下面的语句在Java 7中无法编译无法通过
4list.addAll(new ArrayList<>());

Java 8的泛型类型推断改进

java 8里面泛型的目标类型推断主要2个:

  1. 支持通过方法上下文推断泛型目标类型
  2. 支持在方法调用链路当中,泛型类型推断传递到最后一个方法

看看官网的例子:

1class List<E> {
2   static <Z> List<Z> nil() { ... };
3   static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
4   E head() { ... }
5}

根据JEP101的特性,在调用上面方法的时候可以这样写

1//通过方法赋值的目标参数来自动推断泛型的类型
2List<String> l = List.nil();
3//而不是显示的指定类型
4//List<String> l = List.<String>nil();
5
6//通过前面方法参数类型推断泛型的类型
7List.cons(42, List.nil());
8//而不是显示的指定类型
9//List.cons(42, List.<Integer>nil());

参考: