某些情况下,用户需要手动指明类型,建议大家根据自己或项目组的习惯,采用让代码最便于阅读的方法。有时省略类型信息可以减少干扰,更易弄清状况;而有时却需要类型信息帮助理解代码。经验证发现,一开始类型信息是有用的,但随后可以只在真正需要时才加上类型信息。下面将介绍一些简单的规则,来帮助确认是否需要手动声明参数类型。Lambda表达式中的类型推断,实际上是Java 7就引入的目标类型推断的扩展。读者可能已经知道Java7中的菱形操作符,它可使javac推断出泛型参数的类型。参见例1-1。
例1-1 使用菱形操作符,根据变量类型做推断
Map<String, Integer> one = new HashMap<String, Integer>();//1
Map<String, Integer> two = new HashMap<>();//2
我们为变量one明确指定了泛型的类型, 而变量two 则使用了菱形操作符。不用明确声明泛型类型,编译器就可以自己推断出来,这就是它的神奇之处!当然,这并不是什么魔法,根据变量two 的类型可以推断出HashMap的泛型类型,但用户仍需要声明变量的泛型类型。如果将构造函数直接传递给-一个方法, 也可根据方法签名来推断类型。在例2-10中,我们传入了HashMap,根据方法签名已经可以推断出泛型的类型。
例1-2 使用菱形操作符,根据方法签名做推断
public static void main(String[] args) {
testM(new HashMap<>()); //1
}
public static void testM(HashMap<String,String> hashMap){ //2
}
Java7中程序员可省略构造函数的泛型类型,Java8更进–步,程序员可省略Lambda表达
式中的所有参数类型。再强调一次,这并不是魔法,javac 根据Lambda表达式上下文信息
就能推断出参数的正确类型。程序依然要经过类型检查来保证运行的安全性,但不用再显
式声明类型罢了。这就是所谓的类型推断。
下面将举例详细分析类型推断
例1-3和例1-4都将变量赋给-一个函数接口,这样便于理解。第一个例子(例1-3) 使
用Lambda表达式检测-一个Integer是否大于5。这实际,上是一个Predicate一用 来判断
真假的函数接口。
例1-3 类型推断
Predicate<Integer> atLeast5 = x -> x > 5;
Predicate也是一一个Lambda表达式,和前文中ActionListener不同的是,它还返回一个
值。在例1-3中,表达式x > 5是Lambda表达式的主体。这样的情况下,返回值就是
Lambda表达式主体的值(boolean)。
例1-4 Predicate接口的源码,接受-一个对象,返回一个布尔值
public interface Predicate<T> {
boolean test(T t);
}
从例1-4中可以看出,Predicate 只有一一个泛型类型的参数,Integer 用于其中。Lambda
表达式实现了Predicate接口,因此它的单一参数被推断为Integer类型。javac 还可检查
L ambda表达式的返回值是不是boolean,这正是Predicate方法的返回类型(如图1-5)。
例1-5 Predicate接口图示,接受一个对象,返回一个布尔值
大家如果感觉我写的不太清楚可以去看java8函数式编程这本书。
下载地址:https://306t.com/file/28095605-451122547
提取码:123456