java11新特性--Local-Variable Syntax for Lambda Parameters

宋兵甲發表於2018-09-29

簡介

允許在隱式型別的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()複製程式碼


相關文章