© 2021 NTT DATA Corporation
9/14にリリースされたばかりの新LTS版Java 17
ここ3年間のJavaの変化を知ろう!
2021年9月18日 Open Source Conference 2021 Online Hiroshima
株式会社NTTデータ
阪田 浩一
2
© 2021 NTT DATA Corporation
自己紹介
 株式会社NTTデータ 所属
 Javaチャンピオン
 OpenJDK Author (開発者権限が少しある)
 JVMがとにかく好き
阪田 浩一
jyukutyo
3
© 2021 NTT DATA Corporation
このセミナーの対象と想定している方
 Javaを使っている 学んでいる方
 新バージョンの機能は知らない 追い切れてないなあ…
という方にもぴったりです
© 2020 NTT DATA Corporation
Java 17リリース!
5
© 2021 NTT DATA Corporation
Java 17
 9月14日(米国時間)リリース
 LTSバージョンとしてJava 11以来3年ぶり
 https://openjdk.java.net/projects/jdk/17/
6
© 2021 NTT DATA Corporation
LTS: Long Term Support
 長期サポートバージョン
• バイナリ提供者によって期間が異なる
• 有償サポート契約の場合8年などさらに長期に
• LTS以外のバージョンを数年間有償サポートするベンダも
バージョン 期間
LTS 3年以上
LTS以外 半年
7
© 2021 NTT DATA Corporation
Javaのリリースサイクル
バージョン LTS? リリース日
8 ○ 2014/03
9 2017/09
10 2018/03
11 ○ 2018/09
12 2019/03
13 2019/09
14 2020/03
15 2020/09
16 2021/03
17 ○ 2021/09
10以降リリースが半年ごとに
(3、9月)
LTS以外のサポート期間半年とは
つまり次バージョンのリリースまで
LTSは3年ごと サポート期間も
少なくとも次のLTSまで = 3年
2021年9月最新情報
LTSを2年ごとに変更する提案が…
8
© 2021 NTT DATA Corporation
このセッションでお話する内容
バージョン LTS? リリース日
8 ○ 2014/03
9 2017/09
10 2018/03
11 ○ 2018/09
12 2019/03
13 2019/09
14 2020/03
15 2020/09
16 2021/03
17 ○ 2021/09
8の新機能: ラムダ式
9の新機能: モジュール
LTSの11よりあとの
6バージョン
“Javaプログラムを
書く、実行する”ときに
関わる新機能について
© 2020 NTT DATA Corporation
言語構文編
10
© 2021 NTT DATA Corporation
レコード: Record
 データの入れ物 フィールドを集めただけのクラス
class Customer {
private final long id;
private final String name;
public Customer(long id, String name) {
this.id = id;
this.name = name;
}
// 通常あとgetter, equals, hashCode, toString
定型的、冗長なコード
(LombokやIDEなどを使ったとしても
コードとしては存在する)
11
© 2021 NTT DATA Corporation
レコード: Record
 データの入れ物 フィールドを集めただけのクラス
 上記のような“不変なクラス”は
レコードを使うと簡単に定義できる
record Customer (long id, String name) {}
// コンストラクタ、フィールドの値取得, equals, hashCode, toStringは
// レコードの機能によって定義される
不変なためsetterは存在しない
(フィールドはすべてfinal)
12
© 2021 NTT DATA Corporation
レコードの実体
record Customer (long id, String name) {}
$ javap -private Customer
Compiled from "Customer.java"
final class Customer extends java.lang.Record {
private final long id;
private final java.lang.String name;
Customer(long, java.lang.String);
public final java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object);
public long id();
public java.lang.String name();
}
13
© 2021 NTT DATA Corporation
レコード: Record
 Java 16 から正式に利用できる
 Java 14: プレビュー
 Java 15: 2ndプレビュー
 Java 16: スタンダード
プレビュー??
14
© 2021 NTT DATA Corporation
Preview、Incubator、Experimental
Preview
完成しているが
標準化はしていない機能
--enable-previewオプション
でプレビュー機能が有効に
Incubator 実験的なAPIやツール
jdk.incubatorで始まる
モジュール
変更、削除の可能性あり
Experimental
ランタイムの
試験的機能
ガベージコレクタや
JITコンパイラなどの新機能
--UnlockExperimentalVMOptions
オプションと対象機能を
有効にするオプションを
付与して実行する
15
© 2021 NTT DATA Corporation
レコード: Record
 Java 16 から正式に利用できる
 Java 14: プレビュー
 Java 15: 2ndプレビュー
 Java 16: スタンダード
プレビューを経る機能は
名称が同じでも各バージョンで
使用方法などが異なる場合があります
16
© 2021 NTT DATA Corporation
レコードのカスタマイズ
 コンストラクタ、メソッドの独自定義もできる
record Customer (long id, String name) {
public Customer {
name += "-San";
}
@Override
public String toString() {
return "Hello " + name;
}
}
jshell> Customer c = new Customer(1, "Sakata")
c ==> Customer[id=1, name=Sakata-San]
コンパクトコンストラクタ:
引数はレコードの宣言順と同じ
記述せずとも引数の値を
フィールドに代入する
17
© 2021 NTT DATA Corporation
JShell
 Javaの対話型ツール、REPL
 Java 9で導入
 ちょっとしたコードや新機能を試すときに便利
$ jshell
| JShellへようこそ -- バージョン17
| 概要については、次を入力してください: /help intro
jshell>
$ jshell --enable-preview
18
© 2021 NTT DATA Corporation
レコードが宣言できる場所
 ローカルレコードクラス
 メソッド内部でレコードを定義できる
 レコードを名前付きのタプルと捉えてもよい
public static void main(String... args) {
record Customer(long id, String name) {}
Customer c = new Customer(1, "Sakata");
}
19
© 2021 NTT DATA Corporation
レコード: Record
 データ格納用の不変なオブジェクトを定義する
 ScalaのケースクラスやKotlinのデータクラスに近い
 JavaBeansとの互換性はない
 レコードの実体はfinalなクラスである
record Customer (long id, String name) {}
// コンストラクタ、フィールドの値取得, equals, hashCode, toStringは
// レコードの機能によって定義される
20
© 2021 NTT DATA Corporation
switch式
 今まであったのはswitch“文”
enum Day { MONDAY, TUESDAY, ...}
Day day = getDay();
String kanji;
switch (day) {
case MONDAY:
kanji = "月";
break;
case TUESDAY:
...
}
文なのでswitchから値は返せない
case節の中で代入する必要があった
21
© 2021 NTT DATA Corporation
switch式
 switch“式”で値を返せる
enum Day { MONDAY, TUESDAY, ...}
Day day = getDay();
String kanji = switch (day) {
case MONDAY:
yield "月";
case TUESDAY:
...
}
値を返すときは
yieldを使う
22
© 2021 NTT DATA Corporation
switch式
 ラムダ式のような書き方もできる
enum Day { MONDAY, TUESDAY, ...}
Day day = getDay();
String kanji = switch (day) {
case MONDAY -> "月";
case TUESDAY -> "火";
...
case FRIDAY, SATURDAY -> "金or土";
}
式の中でcase節の書き方は
どちらかに統一すること
フォールスルーしない
breakが不要になった
23
© 2021 NTT DATA Corporation
switch式
 Java 14 から正式に利用できる
 Java 12: プレビュー
 Java 13: 2ndプレビュー
 Java 14: スタンダード
プレビューは2回という決まりはありません
プレビュー1回のあと標準化する
可能性もあります
24
© 2021 NTT DATA Corporation
instanceofでのパターンマッチ
 Javaにパターンマッチを導入するはじめの一歩
 少しずつパターンマッチのための機能が入っている
// 従来
if (a instanceof String) {
String s = (String) a; // キャストが必要
if (s.length() > 3)
a = s.replaceAll("java", "Java");
}
// instanceofでのパターンマッチ
if (a instanceof String s && s.length() > 3) {
a = s.replaceAll("java", "Java"); // このブロック内では変数sが使える
}
条件式も
組み合わせられる
25
© 2021 NTT DATA Corporation
switchでのパターンマッチ
 instanceofに続きswitchでも同様のことができる
Object o = ...;
String message = switch (o) {
case Integer i -> "int";
case Long l -> "long";
case Double d -> "double";
case String s && s.length() > 3 -> "String";
case null -> "null";
default -> o.toString();
}
Java 17ではまだプレビュー機能
nullにもマッチさせられる
switchにObjectを渡せる
26
© 2021 NTT DATA Corporation
パターンマッチ
 instanceofでのパターンマッチ
 Java 14: プレビュー
 Java 15: 2ndプレビュー
 Java 16: スタンダード
 switchでのパターンマッチ
 Java 17: プレビュー
 Java 18でレコードと配列にも使用できる予定
27
© 2021 NTT DATA Corporation
Sealed Classes: シールクラス
 そのクラスを継承できるクラスを制限する
 子クラスの制限
 インタフェースにも使用可能
 今までは継承可かfinalにして不可にするかのみ
28
© 2021 NTT DATA Corporation
Sealed Classes: シールクラス
public abstract sealed class Shape
permits Circle, Rectangle, WeirdShape { ... }
// これからCircle、Rectangle、WeirdShapeを定義する
 Shapeを継承できるのはpermitsにある上記3クラスのみ
 継承先クラスは以下の選択が必須
 finalクラスにする: これ以降継承禁止となる
 シールクラスにする: さらなる継承を制限する
 nonシールクラスにする: 自由に継承できる
29
© 2021 NTT DATA Corporation
Sealed Classes: シールクラス
public abstract sealed class Shape
permits Circle, Rectangle, WeirdShape { ... }
public final class Circle extends Shape { ... }
public sealed class Rectangle extends Shape
permits TransparentRectangle { ... }
public non-sealed class WeirdShape extends Shape { ... }
30
© 2021 NTT DATA Corporation
Sealed Classes: シールクラス
シールクラスとして継承先を
Circle, Rectangle, WeirdShapeに制限
finalクラスにして
これ以上の継承を禁止
シールクラスとして
このクラスからの
継承もpermitsで制限
non-sealedなので
自由に継承できる
31
© 2021 NTT DATA Corporation
Sealed Classes: シールクラス
public abstract sealed class Shape
permits Circle, Rectangle, WeirdShape { ... }
public final class Circle extends Shape { ... }
public sealed class Rectangle extends Shape
permits TransparentRectangle { ... }
public final class TransparentRectangle extends Rectangle { ... }
public non-sealed class WeirdShape extends Shape { ... }
public class FooShape extends WeirdShape { ... }
32
© 2021 NTT DATA Corporation
Sealed Classes: シールクラス
 そのクラスを継承できるクラスを制限する
 継承先クラスは同一モジュールにあること
• モジュール化していないときは同一パッケージにあること
 Java 17: スタンダード
 Java 15: プレビュー、Java 16: 2ndプレビュー
33
© 2021 NTT DATA Corporation
シースクラスとswitchを組み合わせる
sealed interface S permits A, B, C {}
final class A implements S {}
final class B implements S {}
record C(int i) implements S {} // レコードの実体はfinalクラス
static int testSealedCoverage(S s) {
return switch (s) {
case A a -> 1;
case B b -> 2;
case C c -> 3;
};
}
シールクラスにより継承先がA、B、Cに
限られるため、default節が不要に
インタフェースにも
使用可能
jshell> testSealedCoverage(new B())
$1 ==> 2
34
© 2021 NTT DATA Corporation
最近のJava
 大きな機能が一度に入るのではなく
小さな機能に分かれて数バージョンに渡って入る
 まるで物語における伏線回収のように
いくつかの機能が出揃ったとき
1つの大きな言語機能ができ上がる
35
© 2021 NTT DATA Corporation
テキストブロック
 複数行の文字列リテラル
// SQL
String query = "SELECT "EMP_ID", "LAST_NAME" " +
"FROM "EMPLOYEE_TB"n" +
"WHERE "CITY" = 'INDIANAPOLIS'n" +
"ORDER BY "EMP_ID", "LAST_NAME";n";
// テキストブロックを使う
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
36
© 2021 NTT DATA Corporation
テキストブロック
 改行のエスケープや行末のスペースなど
細かな制御もできる
 interpolation(文字列補間)は範囲外
 “Hello, {name}! ” のようなことはできない
 String#formatted()メソッドを使う
 Java 15で標準に
37
© 2021 NTT DATA Corporation
$ java Sample
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "String.toString()"
because "Sample.array[0]" is null
at Sample.main(Sample.java:4)
NullPointerExceptionの原因がよりわかりやすく
class Sample {
private static String[] array = { null };
public static void main(String... args) {
array[0].toString();
}
$ java Sample
Exception in thread "main" java.lang.NullPointerException
at Sample.main(Sample.java:4)
Java 14から
38
© 2021 NTT DATA Corporation
StreamにtoList()メソッドを追加
Stream.of("A", "B", "C").map(String::toLowerCase)
.collect(Collectors.toList());
Stream.of("A", "B", "C").map(String::toLowerCase).toList();
Java 16から
 Collectorsを使うことなく
より簡単にListへ変換できる
 変更不可能なListになる
© 2020 NTT DATA Corporation
ランタイム編
40
© 2021 NTT DATA Corporation
ガベージコレクタ
 コレクタの種類の追加(後述)
 G1GCの大幅な改善
 Java 9以降のデフォルトGC
 CMS GCをJava 14で削除
 従来のParallel GCやSerial GCも使用可能
41
© 2021 NTT DATA Corporation
ガベージコレクタとガベージコレクション
 ガベージコレクション
 アプリケーションがもう使用しない
オブジェクト(のメモリ領域)を
再び利用できるようにする(回収する)こと
 ガベージコレクタ
 システムの中で
ガベージコレクションを受け持つ部分のこと
42
© 2021 NTT DATA Corporation
新しいガベージコレクタ
 Java 15で標準化
 ZGC
• Java 11でExperimentalとして導入
 Shenandoah
• Java 12でExperimentalとして導入
• Java 11にバックポート済み
 Java 11で導入
 Epsilon (Experimental)
43
© 2021 NTT DATA Corporation
なぜ新しいガベージコレクタが必要?
 アプリケーションへの要求や実行環境の
多様さに対応するため
 例:テラバイト級のヒープメモリを使用する場合
 例:実行時間が短い場合
44
© 2021 NTT DATA Corporation
ZGC(Java 15以降)
 テラバイト級のヒープを処理できる
 GCでの一時停止時間が最大でも10ms
 スループットの低下も最大15%まで
 リリースごとに改善が進んでいる
 Java 17の時点でZGCは世代別GCではないが
世代別に変更する作業が進んでいる
45
© 2021 NTT DATA Corporation
スループットとレイテンシ
 スループット
 時間あたりの業務処理量
 レイテンシ
 要求を送ってから結果が返ってくるまでの時間
 スループットとレイテンシはトレードオフの関係
 並び立たず
46
© 2021 NTT DATA Corporation
スループットとレイテンシ
 赤の面積の合計(停止時間合計)が
少ないので処理量が多い = 高スループット
 時折処理完了まで長時間かかってしまう
 タイミングによらず短時間で処理できる= 低レイテンシ
 単位時間内の処理量は少なくなってしまう
47
© 2021 NTT DATA Corporation
ZGC(Java 15以降)
 テラバイト級のヒープを処理できる
 GCでの一時停止時間が最大でも10ms
 スループットの低下も最大15%まで
 リリースごとに改善が進んでいる
 Java 17の時点でZGCは世代別GCではないが
世代別に変更する作業が進んでいる
48
© 2021 NTT DATA Corporation
Shenandoah(Java 15以降)
 G1GCと比較してヒープサイズが大きくても
一時停止時間を短く抑えられる
 Oracle JDK、Oracle OpenJDKには含まれない
 レッドハット社が主導して開発した経緯がある
49
© 2021 NTT DATA Corporation
Epsilon(Java 11以降)
 Experimentalな機能
 本番環境ではまだ利用しないこと
 ガベージコレクションをしないガベージコレクタ
 GCによる実行オーバーヘッドの影響をなくす
 試験で使う
 GCがアプリケーションに与える影響を調査する
 実行時間が短いアプリケーションに使う
50
© 2021 NTT DATA Corporation
どのガベージコレクタを使う?
 そのバージョンのデフォルトGCを使う
 Java 9以降はG1GCがデフォルト
 GC系のオプション設定もなしでよい
• JVMがエルゴノミクスにより動的に調整する
 性能を測定しGCが問題と判明すれば変更する
 変更後に再度測定し、必要があれば
オプションを設定してチューニングする
51
© 2021 NTT DATA Corporation
AArch64(Arm 64ビットアーキテクチャ)サポート拡大
 いわゆるM1 Macでも利用可能に
 Windows AArch64はOracle JDK、Oracle OpenJDKにはなく
Microsoft Build of OpenJDKやAzul Zuluで利用可能
OS サポートしたバージョン
Linux Java 9
Windows 16
macOS 17
52
© 2021 NTT DATA Corporation
JVMの実行パフォーマンス改善
 JVMのパフォーマンスは継続的に改善されている
 実行基盤のJavaバージョンを上げるだけで
パフォーマンスが改善する可能性が高い
 LTS間の3年もあると変化量も大きい
 加えてバージョンを上げると情報収集のしやすさや
ツールの機能も増えるため障害解析しやすくなる
• jcmdへの機能追加など
53
© 2021 NTT DATA Corporation
Java 8と17のパフォーマンス比較例
OptaPlanner - How much faster is Java 17? https://www.optaplanner.org/blog/2021/09/15/HowMuchFasterIsJava17.html
ベンチマークでは
平均8.66%の性能向上
© 2020 NTT DATA Corporation
OpenJDK開発編
55
© 2021 NTT DATA Corporation
OpenJDKとJavaの関係
 OpenJDKはJavaのオープンソース実装
 多くのJDKディストリビューションは
OpenJDKのソースをベースにビルドしている
56
© 2021 NTT DATA Corporation
Git、GitHubへの移行
 OpenJDKはGitではなくMercurialを利用していた
 新規開発者への敷居を低くする目的でGitへ移行
 同様にGitHubにリポジトリを移行
 ただしプルリクエストファーストではないので
開発者権限がない場合はメーリングリストへ投稿する
Java 16から
57
© 2021 NTT DATA Corporation
Java 17における組織別issue解決数
The arrival of Java 17! https://blogs.oracle.com/java/post/announcing-java17
58
© 2021 NTT DATA Corporation
新機能はどのように開発されているか
 Javaへの大きな変更(機能追加、削除)は
提案文書としてまとめられている
 JEP: JDK Enhancement Proposal
 OpenJDKコミュニティで議論し実装する
 Java 17では14個のJEPが新たに入った
59
© 2021 NTT DATA Corporation
Java 17
JDK 17 https://openjdk.java.net/projects/jdk/17/
60
© 2021 NTT DATA Corporation
JEPの例
JEP 406: Pattern Matching for
switch (Preview)
https://openjdk.java.net/jeps/406
61
© 2021 NTT DATA Corporation
新機能はどのように開発されているか
 Javaへの小さな変更(機能変更、バグ修正)は
バグ管理システムで扱っている
 JBS: JDK Bug System
 誰でも閲覧可能
 Java 17では2645個のissueを解決
62
© 2021 NTT DATA Corporation
JBS
https://bugs.openjdk.java.net/projects/JDK/issues/
63
© 2021 NTT DATA Corporation
まとめ
 Java 11から3年間で6バージョン
多くの機能追加、改善がなされました
 Java 8からだと9バージョン分!
 今回は言語構文とGC、リポジトリに絞っており、
APIの追加やJVMの機能改善など紹介していない
ことも多くあります
 ぜひ調べて試してみてください!
© 2021 NTT DATA Corporation
本資料に記載されている会社名、商品名、又はサービス名は、各社の登録商標又は商標です

9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 Online Hiroshima 発表資料)

  • 1.
    © 2021 NTTDATA Corporation 9/14にリリースされたばかりの新LTS版Java 17 ここ3年間のJavaの変化を知ろう! 2021年9月18日 Open Source Conference 2021 Online Hiroshima 株式会社NTTデータ 阪田 浩一
  • 2.
    2 © 2021 NTTDATA Corporation 自己紹介  株式会社NTTデータ 所属  Javaチャンピオン  OpenJDK Author (開発者権限が少しある)  JVMがとにかく好き 阪田 浩一 jyukutyo
  • 3.
    3 © 2021 NTTDATA Corporation このセミナーの対象と想定している方  Javaを使っている 学んでいる方  新バージョンの機能は知らない 追い切れてないなあ… という方にもぴったりです
  • 4.
    © 2020 NTTDATA Corporation Java 17リリース!
  • 5.
    5 © 2021 NTTDATA Corporation Java 17  9月14日(米国時間)リリース  LTSバージョンとしてJava 11以来3年ぶり  https://openjdk.java.net/projects/jdk/17/
  • 6.
    6 © 2021 NTTDATA Corporation LTS: Long Term Support  長期サポートバージョン • バイナリ提供者によって期間が異なる • 有償サポート契約の場合8年などさらに長期に • LTS以外のバージョンを数年間有償サポートするベンダも バージョン 期間 LTS 3年以上 LTS以外 半年
  • 7.
    7 © 2021 NTTDATA Corporation Javaのリリースサイクル バージョン LTS? リリース日 8 ○ 2014/03 9 2017/09 10 2018/03 11 ○ 2018/09 12 2019/03 13 2019/09 14 2020/03 15 2020/09 16 2021/03 17 ○ 2021/09 10以降リリースが半年ごとに (3、9月) LTS以外のサポート期間半年とは つまり次バージョンのリリースまで LTSは3年ごと サポート期間も 少なくとも次のLTSまで = 3年 2021年9月最新情報 LTSを2年ごとに変更する提案が…
  • 8.
    8 © 2021 NTTDATA Corporation このセッションでお話する内容 バージョン LTS? リリース日 8 ○ 2014/03 9 2017/09 10 2018/03 11 ○ 2018/09 12 2019/03 13 2019/09 14 2020/03 15 2020/09 16 2021/03 17 ○ 2021/09 8の新機能: ラムダ式 9の新機能: モジュール LTSの11よりあとの 6バージョン “Javaプログラムを 書く、実行する”ときに 関わる新機能について
  • 9.
    © 2020 NTTDATA Corporation 言語構文編
  • 10.
    10 © 2021 NTTDATA Corporation レコード: Record  データの入れ物 フィールドを集めただけのクラス class Customer { private final long id; private final String name; public Customer(long id, String name) { this.id = id; this.name = name; } // 通常あとgetter, equals, hashCode, toString 定型的、冗長なコード (LombokやIDEなどを使ったとしても コードとしては存在する)
  • 11.
    11 © 2021 NTTDATA Corporation レコード: Record  データの入れ物 フィールドを集めただけのクラス  上記のような“不変なクラス”は レコードを使うと簡単に定義できる record Customer (long id, String name) {} // コンストラクタ、フィールドの値取得, equals, hashCode, toStringは // レコードの機能によって定義される 不変なためsetterは存在しない (フィールドはすべてfinal)
  • 12.
    12 © 2021 NTTDATA Corporation レコードの実体 record Customer (long id, String name) {} $ javap -private Customer Compiled from "Customer.java" final class Customer extends java.lang.Record { private final long id; private final java.lang.String name; Customer(long, java.lang.String); public final java.lang.String toString(); public final int hashCode(); public final boolean equals(java.lang.Object); public long id(); public java.lang.String name(); }
  • 13.
    13 © 2021 NTTDATA Corporation レコード: Record  Java 16 から正式に利用できる  Java 14: プレビュー  Java 15: 2ndプレビュー  Java 16: スタンダード プレビュー??
  • 14.
    14 © 2021 NTTDATA Corporation Preview、Incubator、Experimental Preview 完成しているが 標準化はしていない機能 --enable-previewオプション でプレビュー機能が有効に Incubator 実験的なAPIやツール jdk.incubatorで始まる モジュール 変更、削除の可能性あり Experimental ランタイムの 試験的機能 ガベージコレクタや JITコンパイラなどの新機能 --UnlockExperimentalVMOptions オプションと対象機能を 有効にするオプションを 付与して実行する
  • 15.
    15 © 2021 NTTDATA Corporation レコード: Record  Java 16 から正式に利用できる  Java 14: プレビュー  Java 15: 2ndプレビュー  Java 16: スタンダード プレビューを経る機能は 名称が同じでも各バージョンで 使用方法などが異なる場合があります
  • 16.
    16 © 2021 NTTDATA Corporation レコードのカスタマイズ  コンストラクタ、メソッドの独自定義もできる record Customer (long id, String name) { public Customer { name += "-San"; } @Override public String toString() { return "Hello " + name; } } jshell> Customer c = new Customer(1, "Sakata") c ==> Customer[id=1, name=Sakata-San] コンパクトコンストラクタ: 引数はレコードの宣言順と同じ 記述せずとも引数の値を フィールドに代入する
  • 17.
    17 © 2021 NTTDATA Corporation JShell  Javaの対話型ツール、REPL  Java 9で導入  ちょっとしたコードや新機能を試すときに便利 $ jshell | JShellへようこそ -- バージョン17 | 概要については、次を入力してください: /help intro jshell> $ jshell --enable-preview
  • 18.
    18 © 2021 NTTDATA Corporation レコードが宣言できる場所  ローカルレコードクラス  メソッド内部でレコードを定義できる  レコードを名前付きのタプルと捉えてもよい public static void main(String... args) { record Customer(long id, String name) {} Customer c = new Customer(1, "Sakata"); }
  • 19.
    19 © 2021 NTTDATA Corporation レコード: Record  データ格納用の不変なオブジェクトを定義する  ScalaのケースクラスやKotlinのデータクラスに近い  JavaBeansとの互換性はない  レコードの実体はfinalなクラスである record Customer (long id, String name) {} // コンストラクタ、フィールドの値取得, equals, hashCode, toStringは // レコードの機能によって定義される
  • 20.
    20 © 2021 NTTDATA Corporation switch式  今まであったのはswitch“文” enum Day { MONDAY, TUESDAY, ...} Day day = getDay(); String kanji; switch (day) { case MONDAY: kanji = "月"; break; case TUESDAY: ... } 文なのでswitchから値は返せない case節の中で代入する必要があった
  • 21.
    21 © 2021 NTTDATA Corporation switch式  switch“式”で値を返せる enum Day { MONDAY, TUESDAY, ...} Day day = getDay(); String kanji = switch (day) { case MONDAY: yield "月"; case TUESDAY: ... } 値を返すときは yieldを使う
  • 22.
    22 © 2021 NTTDATA Corporation switch式  ラムダ式のような書き方もできる enum Day { MONDAY, TUESDAY, ...} Day day = getDay(); String kanji = switch (day) { case MONDAY -> "月"; case TUESDAY -> "火"; ... case FRIDAY, SATURDAY -> "金or土"; } 式の中でcase節の書き方は どちらかに統一すること フォールスルーしない breakが不要になった
  • 23.
    23 © 2021 NTTDATA Corporation switch式  Java 14 から正式に利用できる  Java 12: プレビュー  Java 13: 2ndプレビュー  Java 14: スタンダード プレビューは2回という決まりはありません プレビュー1回のあと標準化する 可能性もあります
  • 24.
    24 © 2021 NTTDATA Corporation instanceofでのパターンマッチ  Javaにパターンマッチを導入するはじめの一歩  少しずつパターンマッチのための機能が入っている // 従来 if (a instanceof String) { String s = (String) a; // キャストが必要 if (s.length() > 3) a = s.replaceAll("java", "Java"); } // instanceofでのパターンマッチ if (a instanceof String s && s.length() > 3) { a = s.replaceAll("java", "Java"); // このブロック内では変数sが使える } 条件式も 組み合わせられる
  • 25.
    25 © 2021 NTTDATA Corporation switchでのパターンマッチ  instanceofに続きswitchでも同様のことができる Object o = ...; String message = switch (o) { case Integer i -> "int"; case Long l -> "long"; case Double d -> "double"; case String s && s.length() > 3 -> "String"; case null -> "null"; default -> o.toString(); } Java 17ではまだプレビュー機能 nullにもマッチさせられる switchにObjectを渡せる
  • 26.
    26 © 2021 NTTDATA Corporation パターンマッチ  instanceofでのパターンマッチ  Java 14: プレビュー  Java 15: 2ndプレビュー  Java 16: スタンダード  switchでのパターンマッチ  Java 17: プレビュー  Java 18でレコードと配列にも使用できる予定
  • 27.
    27 © 2021 NTTDATA Corporation Sealed Classes: シールクラス  そのクラスを継承できるクラスを制限する  子クラスの制限  インタフェースにも使用可能  今までは継承可かfinalにして不可にするかのみ
  • 28.
    28 © 2021 NTTDATA Corporation Sealed Classes: シールクラス public abstract sealed class Shape permits Circle, Rectangle, WeirdShape { ... } // これからCircle、Rectangle、WeirdShapeを定義する  Shapeを継承できるのはpermitsにある上記3クラスのみ  継承先クラスは以下の選択が必須  finalクラスにする: これ以降継承禁止となる  シールクラスにする: さらなる継承を制限する  nonシールクラスにする: 自由に継承できる
  • 29.
    29 © 2021 NTTDATA Corporation Sealed Classes: シールクラス public abstract sealed class Shape permits Circle, Rectangle, WeirdShape { ... } public final class Circle extends Shape { ... } public sealed class Rectangle extends Shape permits TransparentRectangle { ... } public non-sealed class WeirdShape extends Shape { ... }
  • 30.
    30 © 2021 NTTDATA Corporation Sealed Classes: シールクラス シールクラスとして継承先を Circle, Rectangle, WeirdShapeに制限 finalクラスにして これ以上の継承を禁止 シールクラスとして このクラスからの 継承もpermitsで制限 non-sealedなので 自由に継承できる
  • 31.
    31 © 2021 NTTDATA Corporation Sealed Classes: シールクラス public abstract sealed class Shape permits Circle, Rectangle, WeirdShape { ... } public final class Circle extends Shape { ... } public sealed class Rectangle extends Shape permits TransparentRectangle { ... } public final class TransparentRectangle extends Rectangle { ... } public non-sealed class WeirdShape extends Shape { ... } public class FooShape extends WeirdShape { ... }
  • 32.
    32 © 2021 NTTDATA Corporation Sealed Classes: シールクラス  そのクラスを継承できるクラスを制限する  継承先クラスは同一モジュールにあること • モジュール化していないときは同一パッケージにあること  Java 17: スタンダード  Java 15: プレビュー、Java 16: 2ndプレビュー
  • 33.
    33 © 2021 NTTDATA Corporation シースクラスとswitchを組み合わせる sealed interface S permits A, B, C {} final class A implements S {} final class B implements S {} record C(int i) implements S {} // レコードの実体はfinalクラス static int testSealedCoverage(S s) { return switch (s) { case A a -> 1; case B b -> 2; case C c -> 3; }; } シールクラスにより継承先がA、B、Cに 限られるため、default節が不要に インタフェースにも 使用可能 jshell> testSealedCoverage(new B()) $1 ==> 2
  • 34.
    34 © 2021 NTTDATA Corporation 最近のJava  大きな機能が一度に入るのではなく 小さな機能に分かれて数バージョンに渡って入る  まるで物語における伏線回収のように いくつかの機能が出揃ったとき 1つの大きな言語機能ができ上がる
  • 35.
    35 © 2021 NTTDATA Corporation テキストブロック  複数行の文字列リテラル // SQL String query = "SELECT "EMP_ID", "LAST_NAME" " + "FROM "EMPLOYEE_TB"n" + "WHERE "CITY" = 'INDIANAPOLIS'n" + "ORDER BY "EMP_ID", "LAST_NAME";n"; // テキストブロックを使う String query = """ SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB" WHERE "CITY" = 'INDIANAPOLIS' ORDER BY "EMP_ID", "LAST_NAME"; """;
  • 36.
    36 © 2021 NTTDATA Corporation テキストブロック  改行のエスケープや行末のスペースなど 細かな制御もできる  interpolation(文字列補間)は範囲外  “Hello, {name}! ” のようなことはできない  String#formatted()メソッドを使う  Java 15で標準に
  • 37.
    37 © 2021 NTTDATA Corporation $ java Sample Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toString()" because "Sample.array[0]" is null at Sample.main(Sample.java:4) NullPointerExceptionの原因がよりわかりやすく class Sample { private static String[] array = { null }; public static void main(String... args) { array[0].toString(); } $ java Sample Exception in thread "main" java.lang.NullPointerException at Sample.main(Sample.java:4) Java 14から
  • 38.
    38 © 2021 NTTDATA Corporation StreamにtoList()メソッドを追加 Stream.of("A", "B", "C").map(String::toLowerCase) .collect(Collectors.toList()); Stream.of("A", "B", "C").map(String::toLowerCase).toList(); Java 16から  Collectorsを使うことなく より簡単にListへ変換できる  変更不可能なListになる
  • 39.
    © 2020 NTTDATA Corporation ランタイム編
  • 40.
    40 © 2021 NTTDATA Corporation ガベージコレクタ  コレクタの種類の追加(後述)  G1GCの大幅な改善  Java 9以降のデフォルトGC  CMS GCをJava 14で削除  従来のParallel GCやSerial GCも使用可能
  • 41.
    41 © 2021 NTTDATA Corporation ガベージコレクタとガベージコレクション  ガベージコレクション  アプリケーションがもう使用しない オブジェクト(のメモリ領域)を 再び利用できるようにする(回収する)こと  ガベージコレクタ  システムの中で ガベージコレクションを受け持つ部分のこと
  • 42.
    42 © 2021 NTTDATA Corporation 新しいガベージコレクタ  Java 15で標準化  ZGC • Java 11でExperimentalとして導入  Shenandoah • Java 12でExperimentalとして導入 • Java 11にバックポート済み  Java 11で導入  Epsilon (Experimental)
  • 43.
    43 © 2021 NTTDATA Corporation なぜ新しいガベージコレクタが必要?  アプリケーションへの要求や実行環境の 多様さに対応するため  例:テラバイト級のヒープメモリを使用する場合  例:実行時間が短い場合
  • 44.
    44 © 2021 NTTDATA Corporation ZGC(Java 15以降)  テラバイト級のヒープを処理できる  GCでの一時停止時間が最大でも10ms  スループットの低下も最大15%まで  リリースごとに改善が進んでいる  Java 17の時点でZGCは世代別GCではないが 世代別に変更する作業が進んでいる
  • 45.
    45 © 2021 NTTDATA Corporation スループットとレイテンシ  スループット  時間あたりの業務処理量  レイテンシ  要求を送ってから結果が返ってくるまでの時間  スループットとレイテンシはトレードオフの関係  並び立たず
  • 46.
    46 © 2021 NTTDATA Corporation スループットとレイテンシ  赤の面積の合計(停止時間合計)が 少ないので処理量が多い = 高スループット  時折処理完了まで長時間かかってしまう  タイミングによらず短時間で処理できる= 低レイテンシ  単位時間内の処理量は少なくなってしまう
  • 47.
    47 © 2021 NTTDATA Corporation ZGC(Java 15以降)  テラバイト級のヒープを処理できる  GCでの一時停止時間が最大でも10ms  スループットの低下も最大15%まで  リリースごとに改善が進んでいる  Java 17の時点でZGCは世代別GCではないが 世代別に変更する作業が進んでいる
  • 48.
    48 © 2021 NTTDATA Corporation Shenandoah(Java 15以降)  G1GCと比較してヒープサイズが大きくても 一時停止時間を短く抑えられる  Oracle JDK、Oracle OpenJDKには含まれない  レッドハット社が主導して開発した経緯がある
  • 49.
    49 © 2021 NTTDATA Corporation Epsilon(Java 11以降)  Experimentalな機能  本番環境ではまだ利用しないこと  ガベージコレクションをしないガベージコレクタ  GCによる実行オーバーヘッドの影響をなくす  試験で使う  GCがアプリケーションに与える影響を調査する  実行時間が短いアプリケーションに使う
  • 50.
    50 © 2021 NTTDATA Corporation どのガベージコレクタを使う?  そのバージョンのデフォルトGCを使う  Java 9以降はG1GCがデフォルト  GC系のオプション設定もなしでよい • JVMがエルゴノミクスにより動的に調整する  性能を測定しGCが問題と判明すれば変更する  変更後に再度測定し、必要があれば オプションを設定してチューニングする
  • 51.
    51 © 2021 NTTDATA Corporation AArch64(Arm 64ビットアーキテクチャ)サポート拡大  いわゆるM1 Macでも利用可能に  Windows AArch64はOracle JDK、Oracle OpenJDKにはなく Microsoft Build of OpenJDKやAzul Zuluで利用可能 OS サポートしたバージョン Linux Java 9 Windows 16 macOS 17
  • 52.
    52 © 2021 NTTDATA Corporation JVMの実行パフォーマンス改善  JVMのパフォーマンスは継続的に改善されている  実行基盤のJavaバージョンを上げるだけで パフォーマンスが改善する可能性が高い  LTS間の3年もあると変化量も大きい  加えてバージョンを上げると情報収集のしやすさや ツールの機能も増えるため障害解析しやすくなる • jcmdへの機能追加など
  • 53.
    53 © 2021 NTTDATA Corporation Java 8と17のパフォーマンス比較例 OptaPlanner - How much faster is Java 17? https://www.optaplanner.org/blog/2021/09/15/HowMuchFasterIsJava17.html ベンチマークでは 平均8.66%の性能向上
  • 54.
    © 2020 NTTDATA Corporation OpenJDK開発編
  • 55.
    55 © 2021 NTTDATA Corporation OpenJDKとJavaの関係  OpenJDKはJavaのオープンソース実装  多くのJDKディストリビューションは OpenJDKのソースをベースにビルドしている
  • 56.
    56 © 2021 NTTDATA Corporation Git、GitHubへの移行  OpenJDKはGitではなくMercurialを利用していた  新規開発者への敷居を低くする目的でGitへ移行  同様にGitHubにリポジトリを移行  ただしプルリクエストファーストではないので 開発者権限がない場合はメーリングリストへ投稿する Java 16から
  • 57.
    57 © 2021 NTTDATA Corporation Java 17における組織別issue解決数 The arrival of Java 17! https://blogs.oracle.com/java/post/announcing-java17
  • 58.
    58 © 2021 NTTDATA Corporation 新機能はどのように開発されているか  Javaへの大きな変更(機能追加、削除)は 提案文書としてまとめられている  JEP: JDK Enhancement Proposal  OpenJDKコミュニティで議論し実装する  Java 17では14個のJEPが新たに入った
  • 59.
    59 © 2021 NTTDATA Corporation Java 17 JDK 17 https://openjdk.java.net/projects/jdk/17/
  • 60.
    60 © 2021 NTTDATA Corporation JEPの例 JEP 406: Pattern Matching for switch (Preview) https://openjdk.java.net/jeps/406
  • 61.
    61 © 2021 NTTDATA Corporation 新機能はどのように開発されているか  Javaへの小さな変更(機能変更、バグ修正)は バグ管理システムで扱っている  JBS: JDK Bug System  誰でも閲覧可能  Java 17では2645個のissueを解決
  • 62.
    62 © 2021 NTTDATA Corporation JBS https://bugs.openjdk.java.net/projects/JDK/issues/
  • 63.
    63 © 2021 NTTDATA Corporation まとめ  Java 11から3年間で6バージョン 多くの機能追加、改善がなされました  Java 8からだと9バージョン分!  今回は言語構文とGC、リポジトリに絞っており、 APIの追加やJVMの機能改善など紹介していない ことも多くあります  ぜひ調べて試してみてください!
  • 64.
    © 2021 NTTDATA Corporation 本資料に記載されている会社名、商品名、又はサービス名は、各社の登録商標又は商標です