http://openjdk.java.net/jeps/323 を読んだ。
JEP 323: Local-Variable Syntax for Lambda Parameters
Author Brian Goetz Owner Vicente Arturo Romero Zaldivar Created 2017/12/08 15:15 Updated 2018/02/12 17:25 Type Feature Status Targeted Component specification/language Scope SE Discussion amber dash dev at openjdk dot java dot net Effort XS Duration XS Priority 3 Reviewed by Alex Buckley Release 11 Issue 8193259 Relates to JEP 286: Local-Variable Type Inference
Summary
暗黙的に型指定されるラムダ式(implicitly typed lambda expressions)の仮引数宣言でvar
を使用可能にします。
Goals
ローカル変数宣言と暗黙的に型指定されるラムダ式の仮引数宣言でのシンタックスを揃える。
Non-goals
メソッドの仮引数などその他の変数宣言は対象外。
Motivation
ラムダ式は暗黙的な型指定が可能で、この場合はすべての仮引数は型推論されます。
(x, y) -> x.process(y) // 暗黙的に型指定されるラムダ式
Java SE 10ではローカル変数で暗黙的な型指定が使用可能になります。
var x = new Foo(); for (var x : xs) { ... } try (var x = ...) { ... } catch ...
ローカル変数の統一感の観点から、暗黙的に型指定されるラムダ式の仮引数でも'var'を使えるようにしたい、と我々は考えました。
(var x, var y) -> x.process(y) // 暗黙的に型指定されるラムダ式
統一感によるメリットには、修飾子やnotably annotationsをローカル変数とラムダ式の仮引数に、簡潔さを失うことなく、適用できる点です。
@Nonnull var x = new Foo(); (@Nonnull var x, @Nullable var y) -> x.process(y)
Description
暗黙的に型指定されるラムダ式の仮引数で、予約済みの型名var
を使用可能にします。
(var x, var y) -> x.process(y)
上記は以下と同等です。
(x, y) -> x.process(y)
暗黙的に型指定されるラムダ式は、すべての仮引数でvar
を使うか、全く使わないか、のどちらかでなければなりません。また、var
は暗黙的に型指定されるラムダ式の仮引数でだけ使用可能で、明示的に型指定されるラムダ式では引き続きすべての仮引数でマニフェスト型(manifest types)を指定します。よって、マニフェスト型の仮引数を使いつつvar
も使うことは出来ません。以下の使い方は出来ません。
(var x, y) -> x.process(y) // 暗黙的に型指定されるラムダ式で'var'と'非var'を一緒には使えない (var x, int y) -> x.process(y) // 暗黙的に型指定されるラムダ式で'var'とマニフェスト型を一緒には使えない
理屈の上では、上記例の下側、半明示的な型指定(semi-explicitly typed )(もしくは半暗黙的な型指定(semi-implicitly typed)、どちらに重きを置くかの見方の違いに依る)のようなラムダ式は可能に見えます。しかし、このJEPではそれはスコープ外とし、これは型推論とオーバーロード解決に深く影響するためです。これが、ラムダ式ですべてマニフェスト引数型にするか全くしないか、という制限を設ける主な理由です。同様に、暗黙的に型指定されるラムダ式の引数での型推論もvar
を使うか全く使わないか、という制限を設ける考えです。将来のJEPでこの部分推論(partial inference)の課題に取り組むかもしれません。また、省略のシンタックスの簡潔さを損ないたくないので、以下のような表現が出来るようにはしない予定です。*1
var x -> x.foo()
Alternatives
従来通りJava SE 8 の暗黙的に型指定されるラムダ式の宣言を使用し続ける。
Risks and Assumptions
このJEPの、暗黙的に型指定されるラムダ式の引数名の前にvar
を追加するのは、ソース互換性に関してはノーリスクです。これはvar
なし引数の型推論とvar
の型推論は同一なためです。
*1:Also, we do not wish to compromise the brevity of the shorthand syntax, so we won't allow expressions like:が原文。compromise がよくわからん