Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

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文の出現順に依存していたため直感的ではなく、それが潜在バグの元にもなってきた。

//今までの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」オプションをつけないとエラーになります。

qualysite
地方を拠点とし、成長への意欲と技術力を高め続けるプロフェッショナル集団
https://www.qualysite.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away