--- title: 3分で分かった気になれるJDK12 tags: Java JDK12 AdventCalendar author: tshk_mtsys slide: false --- [Java Advent Calendar 2018](https://qiita.com/advent-calendar/2018/java) 14日目の記事です。 JDK12が来年リリースされる予定なので、12の変更内容について一部紹介します。 #Features JDK12に含まれるJEP(JDK Enhancement Proposal)は以下 2018/12/6時点 89: Shenandoah: A Low-Pause-Time Garbage Collector   (Experimental) 230: Microbenchmark Suite **325: Switch Expressions (Preview)** **326: Raw String Literals (Preview)**  ←JDK12からdropされるかも(2018/12/14更新) 334: JVM Constants API 340: One AArch64 Port, Not Two 341: Default CDS Archives 344: Abortable Mixed Collections for G1 346: Promptly Return Unused Committed Memory from G1 https://openjdk.java.net/projects/jdk/12/ 本記事ではJava構文に関する変更で多くのJavaプログラマーにとって影響のある2つ - 「325: Switch Expressions (Preview)」 - 「326: Raw String Literals (Preview)」 について解説する。 #JEP325: Switch Expressions (Preview) Project Amberの一仕様である。Javaのswitch構文の表現を少し改善するもの。 今までのswitch構文は、break文の出現順に依存していたため直感的ではなく、それが潜在バグの元にもなってきた。 ```java //今までのswitch文 switch (day) { case MONDAY: case FRIDAY: case SUNDAY: System.out.println(6); break; case TUESDAY: System.out.println(7); break; case THURSDAY: case SATURDAY: System.out.println(8); break; case WEDNESDAY: System.out.println(9); break; } ``` 以下は改善されたswitch文 ```java //改善されたswitch文 switch (day) { case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); case TUESDAY -> System.out.println(7); case THURSDAY, SATURDAY -> System.out.println(8); case WEDNESDAY -> System.out.println(9); } ``` - caseのラベルが複数書ける - ->でラムダ式のように書ける - break文が不要 かなりスッキリ:relaxed: ###変数への代入ケース switch文でよくあるケースとして変数への代入がある。 ```java //今までのswitch文 int numLetters; switch (day) { case MONDAY: case FRIDAY: case SUNDAY: numLetters = 6; break; case TUESDAY: numLetters = 7; break; case THURSDAY: case SATURDAY: numLetters = 8; break; case WEDNESDAY: numLetters = 9; break; default: throw new IllegalStateException("Wat: " + day); } ``` いちいち各case内で代入処理を書いているが、これが以下のように書ける。 ```java //改善されたswitch文 int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; }; ``` あと、こんな書き方もできる。 ```java int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY: break 6; case TUESDAY: break 7; case THURSDAY, SATURDAY: break 8; case WEDNESDAY: break 9; }; ``` ###エラーパターン いくつか気をつけること ケース1 ```java final int num = 3; String str = switch(num) { case 1 -> "one"; case 2 -> "two"; }; ``` この書き方はコンパイルエラーになる。 エラーメッセージは「the switch expression does not cover all possible input values」 つまり、switchの引数が取りうる値は全てswitchの条件分岐としてカバーしろよ!ということ。 この場合は、intの取りうる値を全てcaseに書けば解決:rolling_eyes:(てバカ ではなく、defaultを書いておけばビルド成功します。 ```java final int num = 3; String str = switch(num) { case 1 -> "one"; case 2 -> "two"; default -> "non"; }; ``` ケース2 ```java final int num = 3; String str = switch(num) { case 1: break "one"; case 2 -> "two"; default -> "non"; }; ``` これもコンパイルエラーになる。 エラーメッセージは「different case kinds used in the switch」 書き方を統一しろや!てこと。 #326: Raw String Literals (Preview) 文字列リテラルの表現がシンプルになる。 URLパスや正規表現、複数行文字列をソースコード内に書くとき、今まではいちいちエスケープしたり改行入れたりして生産性も可読性も落ちてたけど、そんな煩わしさから解放される。 「"(ダブルクォート)」ではなく、「`(バッククォート)」で文字列を囲む。 ファイルパスの例 ```java Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar"); Runtime.getRuntime().exec(`"C:\Program Files\foo" bar`); ``` 正規表現の例 ```java System.out.println("this".matches("\\w\\w\\w\\w")); System.out.println("this".matches(`\w\w\w\w`)); ``` 複数行の例 ```java String html = "\n" + " \n" + "

Hello World.

\n" + " \n" + "\n"; String html = `   

Hello World.

`; ``` #最後に どちらもPreviewステータスなので、今後変更が入ることもあるかもしれませんし、実際の本番(業務)で使えるのはJDK13以降になると思います。なのでJDK12では触れて遊ぶ程度に楽しんでください。 あと、コンパイルと実行時には「--enable-preview」オプションをつけないとエラーになります。