Java 25 は長期サポート (LTS) リリースであり、今日の Java 8、11、17、または 21 で実行されるチームの自然なターゲットになります。 LTS の各リリースには長年の更新プログラムとセキュリティ修正プログラムが適用されるため、Java 25 に移行すると、アプリケーションはサポートされ、セキュリティで保護され、最新のパフォーマンスと言語の改善を使用できます。
問題は、新しい LTS リリースに移行する必要 があるかどうか ではなく、いつ行うべきかという 問題ではありません。 待つ時間が長いほど、現在のバージョンと次にサポートされているバージョンの間に、より多くの変更が蓄積されます。 Java 25 への移行には明確な利点があり、後でなく早く移行を計画するとリスクが軽減されます。
Java 8 以降、すべてのリリースで機能と機能強化が追加されています。 起動時間、スループット、メモリ使用量、スケーラビリティ、開発者の生産性の向上に加えて、API に顕著な追加と変更が加えられています。 この記事では、Java 11 LTS リリース以降に提供されたJava バージョン (Java 17、Java 21、Java 25) に焦点を当てて、最も影響の大きい変更について説明します。
Java 25 への移行
段階的にJava 25 に移行できます。 古い JDK で開発およびビルドされたコードは、通常、再コンパイルなしで Java 25 で実行できます。 メジャー アップグレードと同様に、削除された API、非推奨のパッケージ、内部 API の使用、および既定の動作 (特にガベージ コレクションに関する変更) を監視します。
Java 8 または 11 から始める場合は、Java 8 から Java 11 への移行から始めて、最大の破壊的変更に対処してから、Java 17、21、25 に進みます。 Java 17 または 21 を既に使用している場合は、モジュール システムとほとんどのプラットフォームの変更が既に遅れているため、通常、Java 25 への移行は小さくなります。
ヒント
GitHub Copilot アプリモダン化は、アプリケーションの評価、アップグレードの計画、コード変更の自動適用に役立ちます。 バージョン 8、11、17、21、25 Java間のアップグレードをサポートし、変更後にプロジェクトをビルドしてテストし、この記事で後述する動作の変更を修復するのに役立ちます。
ヒント
古い JDK 用にチューニングされた JVM フラグは、Java 25 で非推奨、削除、または最適ではない可能性があります。 古い設定を引き継ぐ代わりに、jazに、JDK バージョンとコンテナーまたは仮想マシン リソースに合わせた JVM フラグを自動的に適用することができます。
javaコマンドを起動スクリプトのjazに置き換えるか、Dockerfileしてメリットを得る。
Java 11 以降の大まかな変更
このセクションでは、Java 8 以降に行われたすべての変更を列挙するわけではありません。 パフォーマンス、スケーラビリティ、診断、生産性、セキュリティに最も大きな影響を与える変更が強調表示されています。 これらの機能のほとんどは、Java 17、21、および 25 リリースに到着し、Java 25 で取得する LTS ベースラインの一部になりました。 各機能は、統合されたJavaリリースを記録します。
仮想スレッドを使用したスケーラビリティ
仮想スレッド [1] は軽量スレッドであり、オペレーティング システムではなく JVM によって管理されるため、高スループットの同時実行アプリケーションの作成と実行のコストが大幅に削減されます。 仮想スレッドを使用すると、要求ごとの単純なスレッド スタイルでコードを記述でき、多数の同時操作に拡張できます。これは、I/O バインドマイクロサービスや要求応答ワークロードに最適です。
仮想スレッドは、Java 21 で終了しました。 Java 24 では、キャリア スレッドをピン留めせずに仮想スレッドを同期できるようにすることで重要な制限が削除されました [2]。これにより、synchronized ブロックを使用するコードのスケーラビリティが向上します。
構造化コンカレンシーとスコープ値
スコープ値 [3] は、仮想スレッドを含め、スレッド間で不変データを安全かつ効率的に共有する方法を提供します。 これは、スレッドローカル変数に代わる最新の代替手段で、タスクごとのスレッド モデルで適切に機能します。
構造化コンカレンシー [4] は、関連する同時実行タスクのグループを 1 つの作業単位として扱い、エラー処理と取り消しを簡略化します。 Java 21 で最初にプレビューされ、進化し続け、仮想スレッドと自然にペアになります。
言語の生産性
Java 14 から Java 25 までで提供される一連の言語拡張機能により、コードがより簡潔で安全で、読みやすくなりました。
-
Switch 式 [5] (Java 14) を使用すると、
switch値を返し、よりクリーンな矢印構文を使用できます。 -
instanceofのパターンマッチング [6] (Java 16) では、型チェックの後に明示的なキャストが不要になります。 - Records [7] (Java 16) は、固定された一連の値を保持する透過的なキャリアとして不変データを表現し、定型コードを削減します。
- シール クラス [8] (Java 17) を使用すると、型を拡張または実装できるクラスを制御できます。
- テキスト ブロック [9] (Java 15) は、複数行の文字列リテラルを簡略化します。
-
switchのパターン マッチング[10] (Java 21) とレコード パターン [11] (Java 21) を使用すると、複雑な条件付きロジックとデータの構造化を明確かつ安全に表現できます。 - シーケンスコレクション [12] (Java 21) は、最初と最後の要素へのアクセスを含む、定義済みの検出順序を持つコレクションの UNIFORM API を追加します。
- 名前のない変数とパターン [13] (Java 22) を使用すると、未使用の変数とパターン コンポーネントを明示的にマークできます。
- モジュール インポート宣言 [14] (Java 25) を使用すると、モジュールのエクスポートされたパッケージ全体を 1 つの宣言でインポートできます。
- コンパクトなソース ファイルとインスタンスのメイン メソッド [15] (Java 25) は、小規模なプログラムに必要な儀式を減らし、Java簡単に学習し、プロトタイプを作成できます。
-
柔軟なコンストラクター本体 [16] (Java 25) を使用すると、
super(...)またはthis(...)を呼び出す前にステートメントを実行でき、検証と初期化が向上します。
パフォーマンスとスタートアップ
いくつかのランタイム変更によって、スループット、メモリ占有領域、および起動時間が向上します。
- コンパクト なオブジェクト ヘッダー [17] (Java 25) は、64 ビット プラットフォーム上のオブジェクト ヘッダーのサイズを小さくします。 この削減により、ヒープ使用量が減少し、メモリ割り当ての多いワークロードのパフォーマンスが向上する可能性があります。
- クラス データ共有 (CDS) は 、実行時にメモリ マッピングアーカイブされたクラスによって起動時間を短縮します。 既定の CDS アーカイブ [18] (Java 12) と動的 CDS アーカイブ [19] (Java 13) を使用すると、手動トレーニングを実行せずにこの機能を簡単に導入できます。
- 事前のクラス読み込みとリンク [20] (Java 24) と、事前に実行されるコマンド ライン エルゴノミックス [21] (Java 25) と事前のメソッド プロファイリング [22] (Java 25) を組み合わせることで、アプリケーション アーカイブにキャプチャされた作業を再利用することで、起動とウォームアップの時間を短縮します。 これらの機能は、Project Leyden がJavaの開始を速くするための取り組みの一環です。
これらの機能強化は、クラウドネイティブおよびサーバーレスのワークロードにとって特に重要です。高速スタートアップと小さなフットプリントにより、直接スケーリングが向上し、コストが削減されます。
ガベージ コレクション
Java 25 には、幅広いワークロードに適した、成熟した低遅延ガベージコレクタが搭載されています。
- ZGC [23] (Java 15) と Shenandoah [24] (Java 15) は、大きなヒープでの低い一時停止時間用に設計された実稼働可能なコレクターです。
- G1GC は引き続き既定のコレクターであり、ネイティブ コードとのよりスムーズな対話のためにリージョンのピン留め [25] (Java 22) など、引き続き改善を受けています。
- 世代別 ZGC [26] (Java 21) は、別の世代を維持することで効率を向上させます。 Java 23 の時点では、ZGC は既定で世代モードで実行されます [27]、非世代モードは Java 24 で削除されました。
- Generational Shenandoah [28] (Java 25) は、メモリ不足下でのスループットと回復性を向上させるために、Shenandoah コレクターに世代モードを追加します。
JVM は、平均ユース ケースの GC の既定値を設定します。 これらの既定値やその他の GC 設定を調整して、アプリケーションの要件に従ってスループットまたは待機時間を最適化します。
ヒント
既定のガベージ コレクターと多くの JVM の既定値はJavaバージョンによって異なるため、Java 8 または 11 用に調整された設定は、Java 25 では最適ではなくなる可能性があります。
Java用 Azure コマンド ランチャー (jaz) は、コンテナーの cgroup メモリと CPU の制限を読み取り、JDK のバージョンと環境に合わせて調整された JVM フラグを自動的に適用します。
診断と可観測性
言語と Java Flight Recorder (JFR) の両方で、リリース間で診断が改善されました。
-
役に立つ NullPointerExceptions [29] (Java 14) では、どの変数が
nullされたかを正確に記述しているため、デバッグが高速化されます。 - JFR イベント ストリーミング [30] (Java 14) を使用すると、ツールはダンプ ファイルからではなく、プロファイリングと診断データを継続的に使用できます。
- JFR CPU 時間プロファイリング [31] (Java 25) では、Linux での CPU 時間ベースの実験的なメソッド プロファイリングが追加されます。
- JFR 協調サンプリング [32] (Java 25) は、スタック サンプリングの安定性を向上させます。
- JFR メソッドのタイミングとトレース [33] (Java 25) を使用すると、アプリケーション コードを変更することなく、特定のメソッドの時間とトレースを行うことができます。
セキュリティと暗号化
Java 25 では、ポスト量子世界の準備など、プラットフォームのセキュリティ体制が強化されます。
- Edwards-Curve デジタル署名アルゴリズム (EdDSA) [34] (Java 15) は、最新の高性能署名スキームを追加します。
- キー カプセル化メカニズム API [35] (Java 21) は、KEM アルゴリズム用の標準 API を提供します。
- 量子耐性暗号は、モジュール格子ベースのキーカプセル化メカニズム (ML-KEM) [36] (Java 24) とデジタル署名アルゴリズム (ML-DSA) [37] (Java 24) の標準的な実装を追加します。
- キー派生関数 API [38] (Java 25) は、キー派生関数の標準 API を提供します。
ネイティブ相互運用性
外部関数とメモリ API [39] (Java 22) は、ネイティブ ライブラリを呼び出してネイティブ メモリにアクセスするための安全で効率的で純粋なJava方法を提供します。 これは、定型句を減らし、安全性を向上させるJavaネイティブ インターフェイス (JNI) の最新の代替品です。
ツールとライブラリ
いくつかの追加により、日常的な開発が改善され、サードパーティ製ツールの必要性が軽減されます。
-
パッケージ 化ツール (
jpackage) [40] (Java 16) は、Java アプリケーション用のネイティブ インストーラーとパッケージを作成します。 - Simple Web Server [41] (Java 18) は、プロトタイプ作成とテストのための最小限の静的ファイル HTTP サーバーを提供します。
- 拡張擬似乱数ジェネレーター [42] (Java 17) は、乱数生成用の新しいインターフェイスと実装を追加します。
想定すべき挙動の変化
Java 11 以降のいくつかの変更によって既定の動作が変更されるため、アップグレードする前に確認してください。
-
JDK 内部を厳密にカプセル化する [43] (Java 17) は、既定でほとんどの内部 API への反射アクセスをブロックします。
sun.*またはその他の内部パッケージにアクセスするコードまたはライブラリには、更新が必要な場合があります。 - 既定では UTF-8 [44] (Java 18) では、UTF-8 が標準Java API の既定の文字セットになります。 プラットフォーム固有の既定の文字セットに依存するアプリケーションの動作が異なる場合があります。
-
削除の最終処理を廃止 [45] (Java 18) すると、
finalize()は最終的に削除されます。try-with-resources またはjava.lang.ref.Cleanerに移行します。 - エージェントの動的読み込みを禁止する準備をする [46] (Java 21) は、実行中の JVM にエージェントが読み込まれるときに警告します。 監視ツールやインストルメンテーション ツールによっては、構成の変更が必要になる場合があります。
ヒント
GitHub Copilot アプリ modernization は、アップグレード時にこれらの動作変更を自動的に評価して対処するのに役立ちます。
コンテナーとクラウド
Docker やその他のコンテナー ランタイム用に導入された JVM のコンテナー認識は、引き続き改善されています。 JVM は、コンテナー制御グループ (cgroup) によって設定された CPU 制約とメモリ制約を読み取り、それに応じてヒープとその他のリソースのサイズを設定します。 Java 25 は、より高速な起動、フットプリントの小さい、仮想スレッドと組み合わせることで、Azureでのコンテナー化およびサーバーレスデプロイに適しています。
Azureコンテナーまたは仮想マシンでJavaワークロードを実行する場合、Java用の Azure コマンド ランチャー (jaz) は、クラウド最適化されたバージョンに適した JVM の既定値を適用できます。
次のステップ
- Java 8 から Java 11 への移行
- Java 11 以降に移行する理由
- Java用Azureコマンド ランチャー
References
[1] Oracle Corporation、"JEP 444: Virtual Threads"(オンライン)。 使用可能: https://openjdk.org/jeps/444。
[2] Oracle Corporation、"JEP 491: ピン留めせずに仮想スレッドを同期する"。(オンライン)。 使用可能: https://openjdk.org/jeps/491。
[3] Oracle Corporation、"JEP 506: Scoped Values"(オンライン)。 使用可能: https://openjdk.org/jeps/506。
[4] Oracle Corporation、"JEP 453: 構造化コンカレンシー (プレビュー)"(オンライン)。 使用可能: https://openjdk.org/jeps/453。
[5] Oracle Corporation、"JEP 361: Switch Expressions"(オンライン)。 使用可能: https://openjdk.org/jeps/361。
[6] Oracle Corporation、"JEP 394: instanceof のパターン マッチング"(オンライン)。 使用可能: https://openjdk.org/jeps/394。
[7] Oracle Corporation, 「JEP 395: レコード」. (オンライン)。 使用可能: https://openjdk.org/jeps/395。
[8] オラクル社「JEP 409: シールドクラス」(オンライン)。 使用可能: https://openjdk.org/jeps/409。
[9] Oracle Corporation、"JEP 378: Text Blocks"(オンライン)。 使用可能: https://openjdk.org/jeps/378。
[10] Oracle Corporation、"JEP 441: スイッチのパターン マッチング"(オンライン)。 使用可能: https://openjdk.org/jeps/441。
[11] Oracle Corporation、"JEP 440: レコード パターン"(オンライン)。 使用可能: https://openjdk.org/jeps/440。
[12] Oracle Corporation、"JEP 431: Sequenced Collections"(オンライン)。 使用可能: https://openjdk.org/jeps/431。
[13] Oracle Corporation, 「JEP 456: 無名の変数とパターン。」(オンライン)。 使用可能: https://openjdk.org/jeps/456。
[14] Oracle Corporation、"JEP 511: Module Import Declarations" (JEP 511: モジュールインポート宣言)(オンライン)。 使用可能: https://openjdk.org/jeps/511。
[15] オラクル社「JEP 512: コンパクトソースファイルおよびインスタンスmainメソッド」(オンライン)。 使用可能: https://openjdk.org/jeps/512。
[16] Oracle Corporation、「JEP 513: 柔軟なコンストラクター本体」。(オンライン)。 使用可能: https://openjdk.org/jeps/513。
[17] Oracle Corporation、「JEP 519: Compact Object Headers」(オンライン)。 使用可能: https://openjdk.org/jeps/519。
[18] Oracle Corporation、"JEP 341: Default CDS Archives."(オンライン)。 使用可能: https://openjdk.org/jeps/341。
Oracle Corporation、"JEP 350: Dynamic CDS Archives"(オンライン)。 使用可能: https://openjdk.org/jeps/350。
[20] Oracle Corporation、"JEP 483: Ahead-of-Time Class Loading & Linking" (JEP 483: Ahead-of-Time Class Loading & Linking)(オンライン)。 使用可能: https://openjdk.org/jeps/483。
[21] Oracle Corporation、「JEP 514: Ahead-of-Time Command-Line Ergonomics」。(オンライン)。 使用可能: https://openjdk.org/jeps/514。
[22] Oracle Corporation、「JEP 515: Ahead-of-Time Method Profiling」。(オンライン) 使用可能: https://openjdk.org/jeps/515。
[23] Oracle Corporation、"JEP 377: ZGC: スケーラブルな低遅延ガベージコレクター"(オンライン)。 使用可能: https://openjdk.org/jeps/377。
[24] Oracle Corporation, 「JEP 379: Shenandoah: 低停止時間ガベージコレクタ。」(オンライン)。 使用可能: https://openjdk.org/jeps/379。
[25] Oracle Corporation、「JEP 423: G1向けリージョンのピン留め」。(オンライン)。 使用可能: https://openjdk.org/jeps/423。
[26] オラクル・コーポレーション「JEP 439: Generational ZGC」(オンライン)。 使用可能: https://openjdk.org/jeps/439。
[27] Oracle Corporation、"JEP 474: ZGC: Generational Mode by Default" (JEP 474: ZGC: Generational Mode by Default)。(オンライン)。 使用可能: https://openjdk.org/jeps/474。
[28] Oracle Corporation、"JEP 521: Generational Shenandoah"(オンライン)。 使用可能: https://openjdk.org/jeps/521。
[29] Oracle Corporation、「JEP 358: Helpful NullPointerExceptions」。(オンライン) 使用可能: https://openjdk.org/jeps/358。
Oracle Corporation、"JEP 349: JFR Event Streaming"(オンライン)。 使用可能: https://openjdk.org/jeps/349。
[31] オラクル社「JEP 509: JFR CPU時間プロファイリング(試験的機能)」(オンライン). 使用可能: https://openjdk.org/jeps/509。
[32] Oracle Corporation、「JEP 518: JFR 協調サンプリング」(オンライン)。 使用可能: https://openjdk.org/jeps/518。
[33] Oracle Corporation,"JEP 520: JFR Method Timing & Tracing" (JEP 520: JFR メソッドのタイミングとトレース)(オンライン)。 使用可能: https://openjdk.org/jeps/520。
[34] Oracle Corporation, "JEP 339: Edwards-Curve Digital Signature Algorithm (EdDSA)。"(オンライン)。 使用可能: https://openjdk.org/jeps/339。
[35] Oracle Corporation、"JEP 452: キーカプセル化メカニズムAPI"(オンライン)。 使用可能: https://openjdk.org/jeps/452。
[36] Oracle Corporation, 「JEP 496: 耐量子計算機モジュール格子ベース鍵カプセル化機構」(オンライン)。 使用可能: https://openjdk.org/jeps/496。
[37] Oracle Corporation、「JEP 497: 耐量子モジュール格子ベースのデジタル署名アルゴリズム」。(オンライン)。 使用可能: https://openjdk.org/jeps/497。
[38] オラクル社「JEP 510: 鍵導出関数API」。(オンライン)。 使用可能: https://openjdk.org/jeps/510。
[39] Oracle Corporation、"JEP 454: Foreign Function & Memory API"(オンライン)。 使用可能: https://openjdk.org/jeps/454。
[40] オラクル・コーポレーション「JEP 392: パッケージング・ツール」(オンライン)。 使用可能: https://openjdk.org/jeps/392。
Oracle Corporation、"JEP 408: Simple Web Server"(オンライン)。 使用可能: https://openjdk.org/jeps/408。
[42] Oracle Corporation「JEP 356: 強化された疑似乱数生成器」(オンライン)。 使用可能: https://openjdk.org/jeps/356。
[43] Oracle Corporation、「JEP 403: JDK内部を強力にカプセル化する。」(オンライン)。 使用可能: https://openjdk.org/jeps/403。
[44] Oracle Corporation、"JEP 400: UTF-8 by Default"(オンライン)。 使用可能: https://openjdk.org/jeps/400。
[45] Oracle Corporation, 「JEP 421: 削除に向けてファイナライゼーションを非推奨化」 (オンライン)。 使用可能: https://openjdk.org/jeps/421。
[46] Oracle Corporation, 「JEP 451: エージェントの動的なロードを禁止する準備」。(オンライン)。 使用可能: https://openjdk.org/jeps/451。