LoginSignup
57
36

More than 1 year has passed since last update.

Java 13新機能まとめ

Last updated at Posted at 2020-07-20

Java 13が2019/9/17にリリースされています。
Java SE 13 Platform JSR 388

ダウンロード

OpenJDKサイトからダウンロードできていました。
https://jdk.java.net/13/

現在はアーカイブサイトからダウンロードできます。
https://jdk.java.net/archive/

LTSではないので、検証目的以外には今からダウンロードする必要もないと思いますけど。
MacやLinuxでのインストールにはSDKMAN!をお勧めします

Oracle OpenJDK以外に無償で商用利用できるディストリビューションとしては、次のようなものがあります。

LTSではないのでAmazon Correttoではリリースされないようです。

Oracle JDKは開発用途には利用できますが、商用利用にはJava SE Subscriptionを購入する必要があります。

JEP

変更はJEPとしてまとまっています。
https://openjdk.java.net/projects/jdk/13/

今回は5つほどJEPが入っています。
JEP 350: Dynamic CDS Archives
JEP 351: ZGC: Uncommit Unused Memory (Experimental)
JEP 353: Reimplement the Legacy Socket API
JEP 354: Switch Expressions (Second Preview)
JEP 355: Text Blocks (Preview)

JEP 355: Text Blocks (Preview)

複数行の文字列リテラルがプレビューとして導入されました。

String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;

スペースのエスケープなどが追加されて、Java 15で標準になります。
詳しい仕様はJava 14の説明のほうをみてください。
Java 14新機能まとめ - Qiita

JEP 354: Switch Expressions (Second Preview)

Switch文を式にします。

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

Java 12と比べると、switch式で値を返す構文がbreakからyieldになりました。

Java 14で標準化されています。
詳しい仕様はJava 14の説明のほうをみてください。
Java 14新機能まとめ - Qiita

JEP 350: Dynamic CDS Archives

-XX:ArchiveClassesAtExitをつけることで実行時にCDSアーカイブを作成します。

使い方はこちらが参考になると思います。

Java 13のDynamic CDSで想像以上に起動速度が速くなった - きしだのHatena

試した感じでは、実行時ではなくふつうにCDSアーカイブ作った方が起動が速かった。
Dynamic CDSよりJava10からある自力ダンプの方が起動が速い - きしだのHatena

JEP 351: ZGC: Uncommit Unused Memory (Experimental)

ZGCでつかってないメモリが解放されるようになります。

JEP 353: Reimplement the Legacy Socket API

TCPソケットAPIを実装しなおして、Project Loomでの非同期処理に対応しています。

API

APIもいくつか変更されています。

String

TextBlocks関連のAPIが追加されています。

ただし、Java 13の時点では@Deprecated指定されているだけでいつでも使えますが、Java 14では--enable-previewをつけたときにだけ使えるようになっています。

formatted

String.formatをインスタンスメソッドとして使えるようにする。

たとえば

callQuery(String.format("select * from table where id=%d", id));

と書いていたものが

callQuery("select * from table where id=%d".formatted(id));

のように書けて便利。
https://bugs.openjdk.java.net/browse/JDK-8203444

translateEscapes

\nなどをエスケープ文字として扱う。
コードを見るとエスケープが入り混じってまぎらわしいですが、文字列中の\nが改行に変換されています。


jshell> var s = "test\\ntest\\n"
s ==> "test\\ntest\\n"

jshell> System.out.println(s)
test\ntest\n

jshell> s.translateEscapes()
$18 ==> "test\ntest\n"

jshell> System.out.println(s.translateEscapes())
test
test

stripIndent

インデントを取り除きます。

Map.ofで要素数1のMapに対するget(null)がぬるぽ

JDK9でMap.ofが追加されています。
JDK9、JDK10では要素数0のときはMap0、要素数1のときMap1、要素数2以上のときMapNのインスタンスが返っていて、Map.of().get(null)nullを返していました。

C:\Users\naoki>java\jdk\jdk-10.0.1\bin\jshell
|  JShellへようこそ -- バージョン10.0.1
|  概要については、次を入力してください: /help intro

jshell> Map.of().get(null)
$1 ==> null

jshell> Map.of(1,2).get(null)
$2 ==> null

jshell> Map.of(1,2,3,4).get(null)
|  java.lang.NullPointerException thrown
|        at ImmutableCollections$MapN.probe (ImmutableCollections.java:779)
|        at ImmutableCollections$MapN.get (ImmutableCollections.java:721)
|        at (#3:1)

JDK11で要素数0の場合もMapNを使うようになってMap.of().get(null)がぬるぽになってます。

C:\Users\naoki>java\jdk\jdk-11.0.1\bin\jshell
|  JShellへようこそ -- バージョン11.0.1
|  概要については、次を入力してください: /help intro

jshell> Map.of().get(null)
|  例外java.lang.NullPointerException
|        at Objects.requireNonNull (Objects.java:221)
|        at ImmutableCollections$MapN.get (ImmutableCollections.java:843)
|        at (#1:1)

jshell> Map.of(1,2).get(null)
$2 ==> null

jshell> Map.of(1,2,3,4).get(null)
|  例外java.lang.NullPointerException
|        at ImmutableCollections$MapN.probe (ImmutableCollections.java:926)
|        at ImmutableCollections$MapN.get (ImmutableCollections.java:846)
|        at (#3:1)

Map.of(1,2).get(null)の場合はJDK9からJDK12までnullを返していました。
JDK13からはMap.of(1,2).get(null)も ぬるぽになります。

以前のバージョンもJDK12.0.2や、JDK11.0.4で修正されています。

ここで、nullチェックのためにrequireNonNullじゃなくてequals呼び出しを使ってるところも面白いですね。

Numberのデフォルトコンストラクタ

Numberクラスにデフォルトコンストラクタが追加されました。
といっても実装はこんな感じです。

public Number() {super();}

これ、定義しなくても暗黙で定義されるので不要ですよね。
なんかlintをだまらせるために追加したっぽい

JapaneseEraへの令和の追加

2019/5/1に新しい元号「令和」が始まりました。
Java 8のアップデートやJava 11、Java 12でもフォーマットやパースでは令和に対応していたのですが、JapaneseEraには正式には定義されていませんでした。
Java 13からJapaneseEra.REIWAが使えるようになりました。

Java 11では元号は決まっていなかったのでNewEraとして表示されていました。

jshell> java.time.chrono.JapaneseDate.now()
$1 ==> Japanese NewEra 2-07-21

11.0.3では元号が決まっていたのでREIWAという表示になりました。

jshell> java.time.chrono.JapaneseDate.of(2020,5,1)
$1 ==> Japanese Reiwa 2-05-01

これに対するJapaneseEra.NEWERAJapaneseEra.REIWAも定義されてはいたのですが、package privateになっていてコードから使えなかったのですが、Java 13からはpublicになって誰でも使えるようになりました。

ツール

rmicに少し変更が入っています。

rmicで--preview-featureがついたものを通さないようにする

rmicをdeprecatedに。そしてそのうち消す

[JDK-8217412] deprecate rmic for removal - Java Bug System

Java 15で消えています。

57
36
1

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
57
36