Slide 1

Slide 1 text

Java 9~17の新機能 2021/06/18 丸山 貴之

Slide 2

Slide 2 text

リリースサイクル • 6ヶ月毎に必ずリリース  開発が間に合わない機能は次以降のバージョンへ • OpenJDKとしてのサポート期間はリリース後6ヶ月間  次バージョンがリリースされたらバグ修正などは行われない • LTSは?  6ヶ月経過後のメンテナンスを担うメンテナーが居れば、引き続きバグ修正が 行われる  Azul社はMid-Term Supportを提供しているので、MTS対象バージョンのメ ンテナーとなっている

Slide 3

Slide 3 text

Javaの新機能の調べ方 • OpenJDKのリリース毎のページを確認する  https://openjdk.java.net にアクセスし、左側のリンクから辿る • JEP (JDK Enhancement Proposal)を見る  タイトルにPreview/Incubator/Experimentalとあるのは試験的な機能 • JSR (Java Specification Requests)を見る  Java 9まではある程度の情報があったが、最近はJEPを見た方が早い • JBS (JDK Bug System)のチケットを見る  https://bugs.openjdk.java.net  release-noteラベルが設定されている物は、リリースノートに記載される  TypeがCSR (Compatibility & Specification Review)の物は、互換性に関する 情報  CSRについてはこちらも参照: https://wiki.openjdk.java.net/display/csr

Slide 4

Slide 4 text

Preview • Javaの文法・構文に関する新機能について試験的な機能としてリリース する際は”Preview”となる • Javaユーザーからのフィードバックを得て改善されていく • 特にルールがあるわけではないが、Standardに昇格する前にPreviewで 2度リリースされることが多い • Preview機能を利用するには実行時に--enable-previewの指定が必要

Slide 5

Slide 5 text

Incubator • 試験的に追加されたモジュール(クラス) • jdk.incubator.~というパッケージ名で提供される • 正式リリース時には別のパッケージに移動 • 特にルールがあるわけではないが、Standardに昇格する前にIncubator で2度リリースされることが多い • Incubatorモジュールを使用するには実行時に --add-modules ${module name}の指定が必要

Slide 6

Slide 6 text

Experimental • JavaVMの試験的な機能  OpenJDKが提供するJavaVM = HotSpotVM • Experimentalな機能を利用するには実行時に -XX:+UnlockExperimentalVMOptionsの指定が必要

Slide 7

Slide 7 text

Java 9 • 2017/09/17リリース (JSR 379) • リリースサイクル変更前の最後のリリース • https://openjdk.java.net/projects/jdk9/ • 91個のJEP

Slide 8

Slide 8 text

Java 9 主な変更点 • バージョン番号表記の変更  Java 8まで: 1.${MAJOR}.0_${MINOR}-b${BUILD}  Java 9以降: ${MAJOR}.${MINOR}.${SECURITY}+${BUILD}  java.version, java.specification.version: 1.8 → 9 • Java Platform Module System (JPMS)  Javaクラスライブラリ自身もモジュールに整理された • ResourceBundle(*.properties)の文字エンコードのデフォルトがUTF-8に  Unicodeエスケープのためのツール native2ascii は削除 • G1 GCのデフォルト化、CMS GCは非推奨に • 新しいツール: jshell, jlink, jdeprscan • 内部APIのカプセル化 • @DeprecatedにforRemoval, sinceが追加 • new HTTP Client (Incubator)

Slide 9

Slide 9 text

Java 9 主なAPIの変更点 • List, Map, Setのstaticファクトリメソッド  List.of(), Map.of(), Map.ofEntries(), Set.of()  これらのメソッドで作成されたList, Map, Setは不変  要素(Mapの場合はキー・値のいずれか)にnullが指定されるとNullPointerException • Optional#or(Supplier>), Optional#ifPresentOrElse(Consumer, Runnable) • Objects#requireNonNullElse(T, T), Objects#requireNonNullElseGet(T, Supplier) • Integer等プリミティブのラッパークラスについてコンストラクタが非推奨  代わりにvalueOfやparseXxxを利用すること • Arrays.asList(x).toArray() returns Object[] (JDK-6260652)  Java 8までは配列のクローン(clone)を返していた(xの型の配列)

Slide 10

Slide 10 text

Java 10 • 2018/03/20リリース (JSR 383) • https://openjdk.java.net/projects/jdk/10/ • 12個のJEP • 一時期、バージョン番号を${YEAR}.${MONTH} (18.3)にするか否かで 混乱があった  ${FEATURE}.${INTERIM}.${UPDATE}.${PATCH}に変更

Slide 11

Slide 11 text

Java 10 Local-Variable Type Inference • JEP 286 (https://openjdk.java.net/jeps/286) • “var”の導入  “var”はキーワードではなく”reserved type name” • ローカル変数を宣言時に初期化する場合、式の右辺によって変数の型を 推論する • 例  var path = Paths.get(name);  var list = new ArrayList();  ダイヤモンド演算子を使うとArrayListになるため注意 • ガイドライン: https://openjdk.java.net/projects/amber/LVTIstyle.html  日本語訳: https://orablogs-jp.blogspot.com/2018/03/style-guidelines-for- local-variable.html

Slide 12

Slide 12 text

Java 10 Application Class Data Sharing • JEP 310 (https://openjdk.java.net/jeps/310) • CDS: OpenJDKに寄贈されたOracle JDKの商用機能。*.classファイル からクラスをロードして作成されたメタデータをファイルにダンプして、 異なるJVMで共有できる機能 • CDSをアプリケーションクラスに拡張 • アプリケーションの起動時間短縮が期待される

Slide 13

Slide 13 text

Java 10 主なAPIの変更点 • List, Map, SetにcopyOfメソッドの追加 (JDK-8177290)  UnmodifiableなList, Map, Setを生成する • Optional#orElseThrow()メソッドの追加 (JDK-8140281)  引数無し  例外が発生する可能性があることを明確に示す、#get()の代替

Slide 14

Slide 14 text

Java 11 • 2018/09/25リリース (JSR 384) • https://openjdk.java.net/projects/jdk/11/ • 17個のJEP • リリースサイクル変更後、最初のLTS

Slide 15

Slide 15 text

Java 11 Java EE関連モジュールの削除 • JEP 320 (https://openjdk.java.net/jeps/320) • JAX-WS, JAXB, JAF, Common Annotations, CORBA, JTAがJava SE・JDKから削除された  Java 9で標準モジュールパスからは外れていたため、利用するには実行時引 数の指定が必要だった • CORBA以外はJava EE (Jakarta EE)が提供するのでそちらを利用すれ ば良い • Java EE (Jakarta EE)サーバーとの相性は最悪。JDK 8の場合はJDK のクラスを利用すれば良いが、JDK 11ではAPサーバーが提供する必要 が生じた

Slide 16

Slide 16 text

Java 11 Deprecate the Nashorn JavaScript Engine • JEP 335 (https://openjdk.java.net/jeps/335) • JavaScriptエンジン”Nashorn”が非推奨(forRemoval=true)に • JavaScript (ECMAScript)の進化の速度にメンテナンスが追いつかなく なった • 移行先としての候補はGraalJS (https://github.com/oracle/graaljs)

Slide 17

Slide 17 text

Java 11 HTTP Client (Standard) • JEP 321 (https://openjdk.java.net/jeps/321) • Java 9でIncubator moduleとして追加されたHTTP Clientの正式版 • jdk.incubator.httpパッケージからjava.net.httpパッケージに移動

Slide 18

Slide 18 text

Java 11 GC関連の変更 • Epsilon GCの追加 (Experimental)  “何もしない”GC (ヒープを確保できなければ即座にOOME)  パフォーマンス測定においてGCの影響を排除するためのGC  JVM開発目的なので、JVM開発者以外が使う事は推奨されない • ZGCの追加 (Experimental) • Shenandoah GCの追加 (Experimental) • 詳しくは”ざっくりわかった気になるモダンGC入門” https://blog.cybozu.io/entry/2018/05/29/080000 を参照

Slide 19

Slide 19 text

Java 11 OracleJDKの商用機能 • Oracleが提供するJDK (OracleJDK)向けの商用機能がOpenJDKに寄贈 され、無償で利用できるようになった  AppCDS (Java 10~)  Flight Recorder (Java 11~)  Mission Control (JDKにはバンドルされなくなったが別途DL可能) • Flight RecorderがJava 11で提供されることになったことに伴い、商用 機能に関連する実行時引数が削除された (JDK-8202331)  -XX:+UnlockCommercialFeatures  -XX:+LogCommercialFeatures

Slide 20

Slide 20 text

Java 11 その他変更点 • いくつかのシステムプロパティがRead Onlyに (JDK-8066709)  java.home  user.home  user.dir  user.name  これらのプロパティは起動時にキャッシュされ変更不可になった

Slide 21

Slide 21 text

Java 11 主なAPIの変更点 • Collection#toArray(IntFunction)の追加 (JDK-8060192)  デフォルトメソッドとしての追加  必要な大きさの配列を作って渡す事が容易に  従来: list.toArray(new String[list.size()])  Java 11: list.toArray(String[]::new) • Predicate#not(Predicate) (JDK-8050818) • Stringに対するメソッドの追加  Stream lines() (JDK-8200380)  String strip(), String stripLeading(), String stripTrailing() (JDK-8200377)  boolean isBlank() (JDK-8200436)  String repeat(int) (JDK-8197594) • Optional#isEmpty() (JDK-8184693)

Slide 22

Slide 22 text

Java 12 • 2019/05/19リリース (JSR 386) • https://openjdk.java.net/projects/jdk/12/ • 8個のJEP

Slide 23

Slide 23 text

Java 12 Switch Expressions (Preview) • JEP 325 (https://openjdk.java.net/jeps/325) • switchを”文”ではなく”式”としても利用できるようにする String value; switch (key) { case "A": value = "alice"; break; case "B": value = "bob"; break; case "C": value = "charlie"; break; default: value = "unknown"; } String value = switch (key) { case "A" -> "alice"; case "B" -> "bob"; case "C" -> "charlie"; default -> "unknown; };

Slide 24

Slide 24 text

Java 12 Default CDS Archives • JEP 341 (https://openjdk.java.net/jeps/341) • Javaクラスライブラリのクラスについて、CDSのアーカイブをデフォ ルトで提供する(64 bit) • CDS自体はJava 11でデフォルト有効になっている(JDK-8197067)ため、 Java 12以降にアップデートするだけで起動時間の短縮が期待できる

Slide 25

Slide 25 text

Java 12 主なAPIの変更点 • String  String indent(int) (JDK-8200434)  JDK-8200434ではString align(int)も追加されているが、Raw String Literals がJDK 12からwithdrawnされた関係で削除されている  R transform(Function super String, ? extends R>) (JDK- 8203442) • 元号”令和”のサポート (JDK-8212941)  Java 11以前のバージョンにもバックポートされている  Java 12の最初のリリースでは”NewEra”、その後”Reiwa”へ修正  java.time.chrono.JapaneseEraへの定数追加はJava 13  参考 “Javaバージョン別の改元(新元号)対応まとめ” https://qiita.com/yamadamn/items/56e7370bae2ceaec55d5

Slide 26

Slide 26 text

Java 13 • 2019/09/17リリース (JSR 388) • https://openjdk.java.net/projects/jdk/13/ • 5個のJEP  Switch ExpressionsはSecond Preview (https://openjdk.java.net/jeps/354)

Slide 27

Slide 27 text

Java 13 Text Blocks (Preview) • JEP 355 (https://openjdk.java.net/jeps/355) • 複数行の文字列リテラルを記述できる新しい文法 • 他プログラミング言語では”ヒアドキュメント”とも • 当初は”Raw String Literals”と呼ばれていた物 String sql = "SELECT *¥n" + "FROM users¥n" + "WHERE user_id = ?;"; String sql = """ SELECT * FROM users WHERE user_id = ?; """;

Slide 28

Slide 28 text

Java 13 Dynamic CDS Archives • JEP 350 (https://openjdk.java.net/jeps/350) • アプリケーションの終了時にAppCDSのアーカイブを生成する • 参考 “Building Class Data Sharing Archives with Apache Maven” https://logico-jp.io/2020/12/20/building-class-data-sharing-archives- with-apache-maven/

Slide 29

Slide 29 text

Java 13 Reimprement the Legacy Socket API • JEP 353 (https://openjdk.java.net/jeps/353) • JDK 1.0から存在するjava.net.Socket, java.net.ServerSocketを再 実装 • 今後の改善を見据えたリファクタリング • システムプロパティjdk.net.usePlainSocketImplを指定することで 旧実装に切り替えることが可能  Socket, ServerSocketの内部実装に依存した処理がある場合は新実装に切り替 えると問題が生じる可能性がある

Slide 30

Slide 30 text

Java 13 主なAPIの変更点 • Text Blocks関係でjava.lang.Stringにいくつかのメソッドが追加  ただし@Deprecated(forRemoval=true)  Text Blocksのフィードバックを受けて変更される可能性があるため • java.time.chrono.JapaneseEraクラスに定数REIWAが追加

Slide 31

Slide 31 text

Java 14 • 2020/03/17リリース (JSR 389) • https://openjdk.java.net/projects/jdk/14/ • 16個のJEP • Switch ExpressionsがStandard🎉  https://openjdk.java.net/jeps/361 • Text BlocksがSecond Preview  https://openjdk.java.net/jeps/368

Slide 32

Slide 32 text

Java 14 Pattern Matching for instanceof (Preview) • JEP 305 (https://openjdk.java.net/jeps/305) • キャストせずにinstanceofで判定した型として扱えるように Object obj; if (obj instanceof String) { String s = (String)obj; System.out.println("obj is String. length = " + s.length()); } Object obj; if (obj instanceof String s) { System.out.println("obj is String. length = " + s.length()); }

Slide 33

Slide 33 text

Java 14 Packaging Tool (Incubator) • JEP 343 (https://openjdk.java.net/jeps/343) • ターゲットOSに適した形式のインストーラーを生成するjpackage  Windows: exe or msi  Mac: pkg or dmg  Linux: deb or rpm • jlinkで作成したカスタムランタイムを同梱できるため、インストー ラーだけ配布すればランタイムとアプリを同時にインストールできる

Slide 34

Slide 34 text

Java 14 Helpful NullPointerException • JEP 358 (https://openjdk.java.net/jeps/358) • 全Javaユーザー待望(?)の機能 • NPEの原因となったnullがどこにあるのかメッセージに記載される • 例  Cannot invoke 'Object.getClass()' because the return value of 'Container.getObj()' is null  container.getObj().getClass();のgetObj()がnullだとすぐに分かる • Java 14ではデフォルトは無効  -XX:ShowCodeDetailsInExceptionMessagesオプションで有効化する

Slide 35

Slide 35 text

Java 14 Records (Preview) • JEP 359 (https://openjdk.java.net/jeps/359) • イミュータブルなクラスを作るための新しい構文の追加 class Point { private final int x; private final int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } } record Point(int x, int y) { }

Slide 36

Slide 36 text

Java 14 Records (Preview) • record Point(int x, int y) { }  指定した引数を受け取るコンストラクタが定義されたクラスとして扱われる  new Point(10, 20) でインスタンス生成可能  x, yは”コンポーネント”と呼ぶ  コンポーネントに対するアクセッサーは、コンポーネントと同じ名前のメ ソッド  getX(), getY()ではなく、x(), y()  アクセッサー以外にequals, hashCode, toStringも実装される  暗黙的にextends java.lang.Record  インタフェースを実装することは可能  record Point(int x, int y) implements Serializable { }  独自のメソッド・コンストラクタも定義可能  引数を変えたコンストラクタを定義する場合、必ず自動生成されるコンストラクタ を呼ぶ必要がある

Slide 37

Slide 37 text

Java 14 主なAPIの変更点 • CSRを確認したが、特に目立った変更はなさそう  java.lang.Recordの追加はあったがその程度

Slide 38

Slide 38 text

Java 15 • 2020/09/15リリース (JSR 390) • https://openjdk.java.net/projects/jdk/15/ • 14個のJEP • Pattern Matching for instanceof, Recordsが Second Preview  https://openjdk.java.net/jeps/375  https://openjdk.java.net/jeps/384 • Text Blocks, ZGC, Shenandoah GCが Standard🎉  https://openjdk.java.net/jeps/378  https://openjdk.java.net/jeps/377  https://openjdk.java.net/jeps/379

Slide 39

Slide 39 text

Java 15 Remove the Nashorn JS Engine • JEP 372 (https://openjdk.java.net/jeps/372) • Java 11でDeprecated(forRemoval=true)となっていたNashornが削除

Slide 40

Slide 40 text

Java 15 Sealed Classes (Preview) • JEP 360 (https://openjdk.java.net/jeps/360) • コンパイルエラーメッセージによると、”シール・クラス” • クラスの継承先を制限する • 例  Circle, Rectangle, Square以外のクラスがShapeを継承しようとするとコン パイルエラー public abstract sealed class Shape permits Circle, Rectangle, Square {...} jshell> class Container extends Shape {} | エラー: | クラスはシール・クラスShapeを拡張できません('permits'句に指定されていないためです) | class Container extends Shape {} | ^------------------------------^

Slide 41

Slide 41 text

Java 15 Sealed Classes (Preview) • Sealed Classを継承するクラスはfinal, sealed, non-sealedのいずれ かを指定する必要がある  final: 非sealed classと同じく、他のクラスが継承することはできない  non-sealed: 継承に制限はない  sealed: permitsに指定したクラスのみ継承可能 • interfaceにも適用可能 public abstract sealed class Shape permits Circle, Rectangle, Square { } public final class Circle extends Shape { } public non-sealed class Rectangle extends Shape { } public sealed class Square extends Shape permits ... { }

Slide 42

Slide 42 text

Java 15 Reimprement the Legacy DatagramSocket API • JEP 373 (https://openjdk.java.net/jeps/373) • JDK 1.0から存在するjava.net.DatagramSocket, java.net.MulticastSocketを再実装  Java 13の”Reimplement the Legacy Socket API”のUDP版 • 今後の改善を見据えたリファクタリング • システムプロパティjdk.net.usePlainDatagramSocketImplを指定す ることで旧実装に切り替えることが可能  内部実装に依存した処理がある場合は新実装に切り替えると問題が生じる可 能性がある

Slide 43

Slide 43 text

Java 15 主なAPIの変更点 • java.lang.StrictMath#absExact(int), #absExact(long), java.lang.Math#absExact(int), #absExact(long) (JDK-8241374)  オーバーフローしない限り、引数の絶対値を返却する  引数がMIN_VALUEの場合はオーバーフローするためArithmeticExceptionが 発生する

Slide 44

Slide 44 text

Java 16 • 2021/03/16リリース (JSR 390) • https://openjdk.java.net/projects/jdk/16/ • 17個のJEP • Git/GitHubへ移行🎉  https://openjdk.java.net/jeps/357  https://openjdk.java.net/jeps/369 • Packaging Tool, Pattern Matching for intanceof, RecordsがStandard🎉  https://openjdk.java.net/jeps/392  https://openjdk.java.net/jeps/394  https://openjdk.java.net/jeps/395 • Sealed ClassesがSecond Preview  https://openjdk.java.net/jeps/397

Slide 45

Slide 45 text

Java 16 Git/GitHubへ移行 • JEP 357, 369  https://openjdk.java.net/jeps/357  https://openjdk.java.net/jeps/369 • VCSをMercurialからGitへ移行 • Gitリポジトリのホスティング先としてGitHubを利用 • JDK開発ツールもGit用に修正 • 課題管理は従来通りJBS (JDK Bug System) を利用する • https://github.com/openjdk

Slide 46

Slide 46 text

Java 16 Unix Domain Socket Channels • JEP 380 (https://openjdk.java.net/jeps/380) • TCPではなく、Unixドメインソケットを介した通信を可能にする  Unixドメインソケット: 同一ホスト内でのプロセス間通信の仕組みの1つ • Unix系OSだけでなく、Windowsでも利用できるようになったため、 Javaも対応した形  Windows 10+, Windows Server 2019+ • InetSocketAddressの代わりにUnixDomainSocketAddressで接続先を 指定する

Slide 47

Slide 47 text

Java 16 Strongly Encapsulate JDK Internals by Default • JEP 396 (https://openjdk.java.net/jeps/396) • Java 9で内部APIを隠蔽する仕組みが導入されていたが、デフォルトで は無効だった (--illegal-access=permit) • Java 16でデフォルト有効となる (--illegal-access=deny) • 制限対象となる内部APIの一覧  https://cr.openjdk.java.net/~mr/jigsaw/jdk8-packages-denied-by-default

Slide 48

Slide 48 text

Java 16 主なAPIの変更点 • Stream#toList() (JDK-8180352)  .collect(Collectors.toUnmodifiableList()) と同じ • プリミティブのラッパークラスのコンストラクタがforRemoval=true に (JDK-8252180)  Java 9で非推奨となったコンストラクタがforRemoval=trueに指定された  valueOfやparseXxxを使いましょう • Year.parse()に3桁以下の年を指定することが可能に (JDK-8245448)

Slide 49

Slide 49 text

Java 17 • 2021/09/14リリース予定 (JSR 392) • https://openjdk.java.net/projects/jdk/17/ • Java 11に続くLTSバージョンとなる見込 • 14個のJEP • Sealed ClassはStandard🎉  https://openjdk.java.net/jeps/409

Slide 50

Slide 50 text

Java 17 Deprecated the Applet API for Removal • JEP 398 (https://openjdk.java.net/jeps/398) • Javaアプレットがついに削除対象に  Java 9の段階でDeprecatedだったが削除対象にはなっていなかった • 全てのWebブラウザーのベンダーがJavaプラグインのサポートを削除 または削除予定となったため、Javaからも削除される方針に

Slide 51

Slide 51 text

Java 17 Strongly Encapsulate JDK internals • JEP 403 (https://openjdk.java.net/jeps/403) • JDK内部APIの隠蔽 • Java 16ではデフォルトで隠蔽されるようになったが、オプションで変 更可能だった • Java 17は--illegal-accessオプションの指定を無視するようになる  内部APIを使わず、標準APIを使いましょう • ライブラリ・フレームワークの一部はこの変更で動作しなくなる恐れが あるため、Java 17を採用する場合はきちんとテストすること  Java 17に限らずテストは必要ですけど

Slide 52

Slide 52 text

Java 17 Deprecate the Security Manager for Removal • JEP 411 (https://openjdk.java.net/jeps/411) • Java 1.0から存在していたSecurity Managerが非推奨 (forRemoval=true) • クライアントサイドJava(アプレットなど)のセキュリティ向上が主な目 的で、サーバサイドで使われることは稀 • アプレットが削除されるのに合わせてSecurity Managerも削除対象に

Slide 53

Slide 53 text

Java 17 Pattern Matching for switch (Preview) • JEP 406 (https://openjdk.java.net/jeps/406) • switchにてパターンマッチを利用可能にする • Sealed Classesと組み合わせると、defaultの記述が不要になる static String formatterPatternSwitch(Object o) { return switch (o) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> o.toString(); }; }

Slide 54

Slide 54 text

Java 17 主なAPIの変更 • java.lang.Process#outputWriter(), #inputReader(), #errorReader() (JDK-8191441)  プロセスの標準入力・標準出力・エラー出力を読み書きするための BufferedReader/PrintWriterを取得できるAPI  元々InputStream/OutputStreamとして取得できるAPIは存在していた • Map.Entry.copyOf(Map.Entry) (JDK-8199318)  Map.EntryをコピーするAPI

Slide 55

Slide 55 text

参考資料 • JDK  9: https://openjdk.java.net/projects/jdk9/  10: https://openjdk.java.net/projects/jdk/10/  11: https://openjdk.java.net/projects/jdk/11/  12: https://openjdk.java.net/projects/jdk/12/  13: https://openjdk.java.net/projects/jdk/13/  14: https://openjdk.java.net/projects/jdk/14/  15: https://openjdk.java.net/projects/jdk/15/  16: https://openjdk.java.net/projects/jdk/16/  17: https://openjdk.java.net/projects/jdk/17/

Slide 56

Slide 56 text

参考資料 • JDK Bug System  https://bugs.openjdk.java.net • JDK 9 Release Notes  https://www.oracle.com/java/technologies/javase/9-relnotes.html • Prepare for Java 9  https://www.slideshare.net/YujiKubota/java9-69782018 • Java新機能(Javaの変更点)  https://www.ne.jp/asahi/hishidama/home/tech/java/uptodate.html • Java in the Box Annex  http://www.javainthebox.com/ • OpenJDKと各種JDKディストリビューションの情報源まとめ #minjava  https://qiita.com/yamadamn/items/2dd26a014791b9557199