简介
允许在隐式类型的lambda表达式中使用var来声明参数
目标
统一隐式类型lambda表达式参数声明语法和普通本地变量声明语法
动机
一个lambda表达式可能是隐式类型的,它的类型是靠推断获得的,如下:
(x, y) -> x.process(y)
复制代码
在java 10中出现了隐式类型的本地变量:
var x = new Foo();
for (var x : xs) { ... }
try (var x = ...) { ... } catch ...
复制代码
为了统一本地变量,我们希望能够在隐式的lambda表达式中使用var声明参数:
(var x, var y) -> x.process(y)
复制代码
这种统一的一个好处就是modifiers(特别是一些注解)可以完全一致的用于本地变量和lambda表达式:
@Nonnull var x = new Foo();
(@Nonnull var x, @Nullable var y) -> x.process(y)
复制代码
描述
对于隐式类型的lambda表达式,允许省略掉var,如下:
@Nonnull var x = new Foo();
(@Nonnull var x, @Nullable var y) -> x.process(y)
复制代码
和下面是等价的
(x, y) -> x.process(y)
复制代码
隐含类型的lambda表达式的参数要么全部使用var,要么全不使用var。并且var只能用于隐含类型的lambda表达式,那些显示类型的lambda表达式是不能用var的,比如下面的例子是不合法的:
(var x, y) -> x.process(y)
(var x, int y) -> x.process(y)
复制代码
理论上说上面的第二种半隐式类型(也有人叫半显示类型),但是它已经超出本JEP的讨论范围了,因为它影响到推断和重载机制。这就是为什么当前强制限制lambda表达式只能是全显示或隐式的原因。我们也强制无论隐式lambda表达式的参数是否带var都不影响推断。我们可能在未来的JEP中解决部分推断的问题,但是我们不希望你以如下速记方式的语法,所以下面的表达式是不合法的:
var x -> x.foo()复制代码