Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java 9~17の新機能 / Java 9 ~ 17 Overview

Java 9~17の新機能 / Java 9 ~ 17 Overview

2021/06/18 社内勉強会

20f8ccd1939fd97953d445e2be6d7941?s=128

Takayuki MARUYAMA

June 18, 2021
Tweet

Transcript

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

  2. リリースサイクル • 6ヶ月毎に必ずリリース  開発が間に合わない機能は次以降のバージョンへ • OpenJDKとしてのサポート期間はリリース後6ヶ月間  次バージョンがリリースされたらバグ修正などは行われない •

    LTSは?  6ヶ月経過後のメンテナンスを担うメンテナーが居れば、引き続きバグ修正が 行われる  Azul社はMid-Term Supportを提供しているので、MTS対象バージョンのメ ンテナーとなっている
  3. 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
  4. Preview • Javaの文法・構文に関する新機能について試験的な機能としてリリース する際は”Preview”となる • Javaユーザーからのフィードバックを得て改善されていく • 特にルールがあるわけではないが、Standardに昇格する前にPreviewで 2度リリースされることが多い •

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

    • Incubatorモジュールを使用するには実行時に --add-modules ${module name}の指定が必要
  6. Experimental • JavaVMの試験的な機能  OpenJDKが提供するJavaVM = HotSpotVM • Experimentalな機能を利用するには実行時に -XX:+UnlockExperimentalVMOptionsの指定が必要

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

    • 91個のJEP
  8. 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)
  9. 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<T>>), Optional#ifPresentOrElse(Consumer<T>, Runnable) • Objects#requireNonNullElse(T, T), Objects#requireNonNullElseGet(T, Supplier<T>) • Integer等プリミティブのラッパークラスについてコンストラクタが非推奨  代わりにvalueOfやparseXxxを利用すること • Arrays.asList(x).toArray() returns Object[] (JDK-6260652)  Java 8までは配列のクローン(clone)を返していた(xの型の配列)
  10. Java 10 • 2018/03/20リリース (JSR 383) • https://openjdk.java.net/projects/jdk/10/ • 12個のJEP

    • 一時期、バージョン番号を${YEAR}.${MONTH} (18.3)にするか否かで 混乱があった  ${FEATURE}.${INTERIM}.${UPDATE}.${PATCH}に変更
  11. 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<String>();  ダイヤモンド演算子を使うとArrayList<Object>になるため注意 • ガイドライン: https://openjdk.java.net/projects/amber/LVTIstyle.html  日本語訳: https://orablogs-jp.blogspot.com/2018/03/style-guidelines-for- local-variable.html
  12. Java 10 Application Class Data Sharing • JEP 310 (https://openjdk.java.net/jeps/310)

    • CDS: OpenJDKに寄贈されたOracle JDKの商用機能。*.classファイル からクラスをロードして作成されたメタデータをファイルにダンプして、 異なるJVMで共有できる機能 • CDSをアプリケーションクラスに拡張 • アプリケーションの起動時間短縮が期待される
  13. Java 10 主なAPIの変更点 • List, Map, SetにcopyOfメソッドの追加 (JDK-8177290)  UnmodifiableなList,

    Map, Setを生成する • Optional#orElseThrow()メソッドの追加 (JDK-8140281)  引数無し  例外が発生する可能性があることを明確に示す、#get()の代替
  14. Java 11 • 2018/09/25リリース (JSR 384) • https://openjdk.java.net/projects/jdk/11/ • 17個のJEP

    • リリースサイクル変更後、最初のLTS
  15. 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サーバーが提供する必要 が生じた
  16. 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)
  17. 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パッケージに移動
  18. 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 を参照
  19. 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
  20. Java 11 その他変更点 • いくつかのシステムプロパティがRead Onlyに (JDK-8066709)  java.home 

    user.home  user.dir  user.name  これらのプロパティは起動時にキャッシュされ変更不可になった
  21. 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<String> lines() (JDK-8200380)  String strip(), String stripLeading(), String stripTrailing() (JDK-8200377)  boolean isBlank() (JDK-8200436)  String repeat(int) (JDK-8197594) • Optional#isEmpty() (JDK-8184693)
  22. Java 12 • 2019/05/19リリース (JSR 386) • https://openjdk.java.net/projects/jdk/12/ • 8個のJEP

  23. 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; };
  24. Java 12 Default CDS Archives • JEP 341 (https://openjdk.java.net/jeps/341) •

    Javaクラスライブラリのクラスについて、CDSのアーカイブをデフォ ルトで提供する(64 bit) • CDS自体はJava 11でデフォルト有効になっている(JDK-8197067)ため、 Java 12以降にアップデートするだけで起動時間の短縮が期待できる
  25. Java 12 主なAPIの変更点 • String  String indent(int) (JDK-8200434) 

    JDK-8200434ではString align(int)も追加されているが、Raw String Literals がJDK 12からwithdrawnされた関係で削除されている  <R> 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
  26. 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)
  27. 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 = ?; """;
  28. 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/
  29. 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の内部実装に依存した処理がある場合は新実装に切り替 えると問題が生じる可能性がある
  30. Java 13 主なAPIの変更点 • Text Blocks関係でjava.lang.Stringにいくつかのメソッドが追加  ただし@Deprecated(forRemoval=true)  Text

    Blocksのフィードバックを受けて変更される可能性があるため • java.time.chrono.JapaneseEraクラスに定数REIWAが追加
  31. 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
  32. 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()); }
  33. 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で作成したカスタムランタイムを同梱できるため、インストー ラーだけ配布すればランタイムとアプリを同時にインストールできる
  34. 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オプションで有効化する
  35. 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) { }
  36. 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 { }  独自のメソッド・コンストラクタも定義可能  引数を変えたコンストラクタを定義する場合、必ず自動生成されるコンストラクタ を呼ぶ必要がある
  37. Java 14 主なAPIの変更点 • CSRを確認したが、特に目立った変更はなさそう  java.lang.Recordの追加はあったがその程度

  38. 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
  39. Java 15 Remove the Nashorn JS Engine • JEP 372

    (https://openjdk.java.net/jeps/372) • Java 11でDeprecated(forRemoval=true)となっていたNashornが削除
  40. 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 {} | ^------------------------------^
  41. 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 ... { }
  42. 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を指定す ることで旧実装に切り替えることが可能  内部実装に依存した処理がある場合は新実装に切り替えると問題が生じる可 能性がある
  43. Java 15 主なAPIの変更点 • java.lang.StrictMath#absExact(int), #absExact(long), java.lang.Math#absExact(int), #absExact(long) (JDK-8241374) 

    オーバーフローしない限り、引数の絶対値を返却する  引数がMIN_VALUEの場合はオーバーフローするためArithmeticExceptionが 発生する
  44. 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
  45. 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
  46. 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で接続先を 指定する
  47. 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
  48. 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)
  49. 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
  50. Java 17 Deprecated the Applet API for Removal • JEP

    398 (https://openjdk.java.net/jeps/398) • Javaアプレットがついに削除対象に  Java 9の段階でDeprecatedだったが削除対象にはなっていなかった • 全てのWebブラウザーのベンダーがJavaプラグインのサポートを削除 または削除予定となったため、Javaからも削除される方針に
  51. 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に限らずテストは必要ですけど
  52. 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も削除対象に
  53. 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(); }; }
  54. 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
  55. 参考資料 • 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/
  56. 参考資料 • 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