最近のJavaでは、
3: var var = var().var;
4: switch (var) {
5: case When when when when.when() -> when();
6: default -> {}
7: }
こういうプログラムが書けるようになります。(元ネタはこちら)
Markdownが最新のJava言語に対応したいないためか、色の付け方に、少し変なところがあります。
そこで、このコードを、Java言語仕様(文法)的に考察してみます。ここでは、仕様としてJava SE 23のJLSを参照しています。
実際に動作する完全コードはこちら。
varの解説
3行目
var var = var().var
(1) (2) (3) (4)
(1) ContextualKeywordの「var」。JLS 1.4.4 Local Variable Declarationsで定義されている「LocalVariableType」。
(2) 「var」というローカル変数名(identifier)。
(3) 「var()」という名前のローカルメソッド呼び出し。
(4) (3)で返却されたインスタンスのクラスに定義された「var」というフィールド名。
whenの解説
5行目
case When when when when.when() -> when();
(5) (6) (7) (8) (9) (10) (11)
(5) ReservedKeyword。
(6) 「When」という名前のクラス名。
(7) 「when」という名前のパターン変数。変数の型は、(6)の「When」クラス。
(8) ContextualKeyword。JLS 14.11.1. Switch Blocks で定義されている「Guard」。
(9) (7)で定義した変数。
(10) 「When」クラスの「when」という名前のインスタンスメソッド呼出し。
(11) 「when()」という名前のローカルメソッド呼出し。
なぜ、ややこしいのか?
こんなコードを書く人はいないと思いますが、このコードをややこしくしている原因は、ContextualKeywordにあります。ContextualKeywordとは、文脈によって、キーワードになったり、ならなかったりするというもので、JLS17で追加された言語仕様です。
そんなにややこしいなら、ContextualKeywordなんかやめて、すべてReservedKeywordにすればいいだろ。
という意見があるかもしれませんが、やたら新しくキーワードを増やすと、これまで動いていたコードが動かなくなってしまいます。互換性を重視するJavaならではの言語仕様の考え方です。