Java 13 の新機能紹介

# Java 13 で何が変わったか
Java 13 になってGCの改善等色々と行われました。
今回はプログラムを書くにあたってわかりやすく変わった以下の変更について紹介します。

- テキストブロック
- switch 式

## 新機能を試してみる
まずは以下のページにある Java 13 をインストールして試してみます。
https://adoptopenjdk.net/

jshell を使って試そうとしたところまだプレビュー版の機能ということで使用できませんでした。
そこで jshell のオプションに --enable-preview を付けて実行します。

```java
jshell --enable-preview
```

## テキストブロック
今までは複数行の文字列を定義する場合 "" で囲み + 演算子で文字列を結合してきました。

```java
jshell> String html = "<html>\n" +
   ...>               "    <body>\n" +
   ...>               "        <p>Sample</p>\n" +
   ...>               "    </body>\n" +
   ...>               "</html>";
```

Java 13 ではテキストブロックという機能が加わり """ で囲むことで複数行で文字列を定義できるようになりました。

```java
jshell> String html = """
   ...>               <html>
   ...>                   <body>
   ...>                       <p>Sample</p>
   ...>                   </body>
   ...>               </html>
   ...>                """;
```

この文字列を出力してみます。

```java
jshell> System.out.println(html);
<html>
    <body>
        <p>Sample</p>
    </body>
</html>
```
上記が出力結果ですが一つ気になるところはあります。
&lt;html&gt;やその他のタグ文字の前方にあるスペースがカットされています。
テキストブロックを使用した場合前方のスペースはコンパイラが判断し不要であれば自動的にカットするようです。

## Switch 式
ある拡張子を渡すとMIME Type を返してくれるメソッドを定義してみます。
今までの Switch 文では以下のような書き方になり、拡張子のパターンが複数ある場合縦に並べて記載しています。

```java
jshell> public String getMimeType(String extension) {
   ...>     String mimeType = "";
   ...>
   ...>     switch(extension.toLowerCase()) {
   ...>         case "gif":
   ...>             mimeType = "image/gif";
   ...>             break;
   ...>         case "jpg":
   ...>         case "jpe":
   ...>         case "jpeg":
   ...>             mimeType = "image/jpeg";
   ...>             break;
   ...>         case "png":
   ...>             mimeType = "image/png";
   ...>             break;
   ...>         default:
   ...>             mimeType = "application/octet-stream";
   ...>     }
   ...>
   ...>     return mimeType;
   ...> }
```

実行結果は以下です。

```java
jshell> System.out.println(getMimeType("GIF"));
image/gif

jshell> System.out.println(getMimeType("JPG"));
image/jpeg

jshell> System.out.println(getMimeType("JPEG"));
image/jpeg
```
### 複数ラベル対応
今までの書き方に加えて Switch 文に複数のラベルをカンマ区切りで宣言することができるようになりました。
先程の書き方よりも見やすくなりましたね。

```java
jshell> public String getMimeType(String extension) {
   ...>     String mimeType = "";
   ...>
   ...>     switch(extension.toLowerCase()) {
   ...>         case "gif":
   ...>             mimeType = "image/gif";
   ...>             break;
   ...>         case "jpg", "jpe", "jpeg":
   ...>             mimeType = "image/jpeg";
   ...>             break;
   ...>         case "png":
   ...>             mimeType = "image/png";
   ...>             break;
   ...>         default:
   ...>             mimeType = "application/octet-stream";
   ...>     }
   ...>
   ...>     return mimeType;
   ...> }
```

### Switch 式
続いて Switch 式になります。
今までの Switch 文に対して戻り値を返すことができるようになりました。
以下のサンプルでは return の横で定義して値を返却してします。
いままでの break とは違い yield を使って値を返すようです。
※ Java12 では `break "image/gif";` のように break を使っていました

```java
public String getMimeType(String extension) {
    return switch(extension.toLowerCase()) {
        case "gif":
            yield "image/gif";
        case "jpg", "jpe", "jpeg":
            yield "image/jpeg";
        case "png":
            yield "image/png";
        default:
            yield "application/octet-stream";
    };
}
```

### アロー構文
さらに返却する際にアロー構文を使用することもできます。
Java 8 から使用できるようになったラムダ式のようになり、かなり完結にかけるようになりました。
アローの後に文字列や数値だけでなく式やブロック等を定義することもできます。

```java
public String getMimeType(String extension) {
    return switch(extension.toLowerCase()) {
        case "gif" -> "image/gif";
        case "jpg", "jpe", "jpeg" -> "image/jpeg";
        case "png" -> "image/png";
        default -> "application/octet-stream";
    };
}
```

## まとめ
Java 13 でも新しい機能が色々と追加されました。
Java 9 から jshell が使用できるようになり、新しいプログラムの書き方に関しては気軽に試すことができるようになっています。
ネットで検索すれば変更点の情報は簡単に見つけることができますが、まずは自分で使って試してみて実感することが重要かと思います。