Project Amberで検討されているJavaの言語仕様にふれてみます。
今回触れるのは以下の言語仕様です。
環境
sdkmanを使ってJDK15のearly accessをインストールして、jshellを使ってコードを書いていきます。 jshell起動時に「--enable-preview」を付けないとpreview機能は使えないので注意が必要です。
$ sdk install java 15.ea.6-open ... $ sdk use java 15.ea.6-open ... $ java --version openjdk 15-ea 2020-09-15 OpenJDK Runtime Environment (build 15-ea+6-123) OpenJDK 64-Bit Server VM (build 15-ea+6-123, mixed mode, sharing) $ jshell --enable-preview | JShellへようこそ -- バージョン15-ea | 概要については、次を入力してください: /help intro jshell>
JEP 286: Local-Variable Type Inference
JDK10から利用できます。 ローカル変数を型推論を使って宣言することができます。
jshell> class Person{ ...> String name; ...> Person(String name){ ...> this.name = name; ...> } ...> String getName(){ ...> return this.name; ...> } ...> } | 次を変更しました: クラス Person jshell> var person = new Person("taro"); person ==> Person@799f7e29 jshell> person instanceof Person $13 ==> true
JEP 323 Local-Variable Syntax for Lambda Parameters
JDK11から利用できます。 var をラムダの引数にも利用できます。varがラムダ の引数に使えるようになることで、ラムダ の引数にfinalやアノテーションをつけることができます。
jshell> var list = List.of(1,2,3); list ==> [1, 2, 3] jshell> List<Integer> result = list.stream().map((final var i)->i*2).collect(Collectors.toList()); result ==> [2, 4, 6]
JEP 325 Switch Expressions, JEP 354 Switch Expressions (Preview, JDK 13), JEP 361: Switch Expressions (Standard)
JDK12, 13ではpreviewとして、JDK14で正式に利用できます。
switchを式として使うことができます。また、今までの:
を使ったラベルに加えて->
を使ったラベルを書くことができます(arrow label)。
jshell> var str = "one"; str ==> "one" jshell> int num = switch(str){ ...> case "zero" -> 0; ...> case "one" -> 1; ...> case "two" -> 2; ...> default -> -1; ...> }; num ==> 1
switchのなかでブロックをそのまま使うとエラーになります。
jshell> var str = "one"; str ==> "one" jshell> int num = switch(str){ ...> case "zero" -> 0; ...> case "one" -> { ...> 1; ...> } ...> case "two" -> 2; ...> default -> -1; ...> }; | エラー: | 文ではありません | 1; | ^ | エラー: | switchルールが値を提供せずに完了しました | (switch式のswitchルールは値またはスローを提供する必要があります) | case "one" -> { | ^
この場合はyieldをつかって値を返すようにします。
jshell> var str = "one"; str ==> "one" jshell> int num = switch(str){ ...> case "zero" -> 0; ...> case "one" -> { ...> yield 1; ...> } ...> case "two" -> 2; ...> default -> -1; ...> }; num ==> 1
JEP 355 Text Blocks, JEP 368: Text Blocks (Second Preview)
JDK13,14でpreviewとして利用できます。
jshell> String html = """ ...> <html> ...> <body> ...> <p>Hello world</p> ...> </body> ...> </html> ...> """; html ==> "<html>\n <body>\n <p>Hello world</p>\n </body>\n</html>\n" jshell> System.out.println(html); <html> <body> <p>Hello world</p> </body> </html>
JEP 305 Pattern Matching for instanceof
JDK14でpreviewとして利用できます。 instanceofを利用したパターンマッチングができます。 パターンマッチングで利用した変数は、マッチした場合のスコープ内で利用することができます。
jshell> class Person{ ...> String name; ...> Person(String name){ ...> this.name = name; ...> } ...> ...> String getName(){ ...> return this.name; ...> } ...> } | 次を作成しました: クラス Person jshell> var taro = new Person("taro"); taro ==> Person@7a07c5b4 jshell> if(taro instanceof Person p){ ...> System.out.println(p.getName()); ...> } taro
JEP 359: Records (Preview)
JDK14でpreviewとして利用できます。 こんな感じで使えます。各フィールドにはフィールド名が名前になったメソッドでアクセスできます。
jshell> record Person(String name, Integer age){} jshell> var taro = new Person("taro", 20); taro ==> Person[name=taro, age=20] jshell> var name = taro.name(); name ==> "taro" jshell> var age = taro.age(); age ==> 20 jshell> var anotherTaro = new Person("taro", 20); anotherTaro ==> Person[name=taro, age=20] jshell> taro.equals(anotherTaro); $9 ==> true