19
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaAdvent Calendar 2018

Day 14

3分で分かった気になれるJDK12

Last updated at Posted at 2018-12-13

Java Advent Calendar 2018 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

本記事ではJava構文に関する変更で多くのJavaプログラマーにとって影響のある2つ

  • 「325: Switch Expressions (Preview)」
  • 「326: Raw String Literals (Preview)」

について解説する。

#JEP325: Switch Expressions (Preview)
Project Amberの一仕様である。Javaのswitch構文の表現を少し改善するもの。

今までのswitch構文は、break文の出現順に依存していたため直感的ではなく、それが潜在バグの元にもなってきた。

//今までの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文

//改善された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文でよくあるケースとして変数への代入がある。

//今までの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内で代入処理を書いているが、これが以下のように書ける。

//改善されたswitch文
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

あと、こんな書き方もできる。

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY: break 6;
    case TUESDAY:                break 7;
    case THURSDAY, SATURDAY:     break 8;
    case WEDNESDAY:              break 9;
};

###エラーパターン

いくつか気をつけること

ケース1

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を書いておけばビルド成功します。

final int num = 3;
String str = switch(num) {
    case 1 -> "one";
    case 2 -> "two";
    default -> "non";
};

ケース2

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パスや正規表現、複数行文字列をソースコード内に書くとき、今まではいちいちエスケープしたり改行入れたりして生産性も可読性も落ちてたけど、そんな煩わしさから解放される。

「"(ダブルクォート)」ではなく、「`(バッククォート)」で文字列を囲む。

ファイルパスの例

Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar");
Runtime.getRuntime().exec(`"C:\Program Files\foo" bar`);

正規表現の例

System.out.println("this".matches("\\w\\w\\w\\w"));
System.out.println("this".matches(`\w\w\w\w`));

複数行の例

String html = "<html>\n" +
              "    <body>\n" +
              "		    <p>Hello World.</p>\n" +
              "    </body>\n" +
              "</html>\n";
String html = `<html>
                    <body>
                       <p>Hello World.</p>
                   </body>
               </html>
              `;

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

19
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?