📝

JDK25のサポート期間とJEP概要

に公開

はじめに

三菱UFJインフォメーションテクノロジーの田中です。
2025年9月16日に、Java 25(JDK 25)がGeneral Availability(GA)となり、正式リリースされました。Java 21(2023年9月リリース)以来、約2年ぶりのLong-Term Support(LTS)となります。
本記事では、JDK 25のサポート期間と各JEPの概要について記載します。
※2025年10月6日時点の情報となります。

JDK 25のダウンロードリンクとサポート期間

各ディストリビューションのダウンロードリンクとサポート期間は以下の通りです。
多くのベンダーが 2030年9月以降 のサポートを提供しています。

ディストリビューション/ダウンロード 提供元 通常サポート期間 延長サポート期間 公式サポート情報リンク
Oracle JDK Oracle 2030年9月まで
(Premier Support)
2033年9月まで
(有償)
リンク
Amazon Corretto Amazon 2032年10月まで 記載なし リンク
Microsoft Build of OpenJDK Microsoft 2030年9月まで 記載なし リンク
Eclipse Temurin Eclipse Foundation 2031年9月まで 記載なし リンク
Liberica JDK BellSoft 2034年3月まで
(有償)
記載なし リンク
SapMachine SAP 2030年9月まで 記載なし リンク
Azul Zulu Azul Systems 2033年9月まで
(有償)
記載なし リンク

※以下はJDK 25に関する情報がありませんでした。リリースされる場合は、以下のページが更新されると思いますので、引き続きウォッチしていきます。


JDK 25で取り込まれたJDK Enhancement Proposal(JEP)

JDK 25の内容は、OpenJDK - JDK 25でまとめられており、18個のJEPが取り込まれました。
これらの機能は、正式機能から試験的機能まで、いくつかの段階に分類されています。

  1. 正式機能(Final Features):11個
  2. プレビュー機能(Preview Features):4個
  3. インキュベーター機能(Incubator Features):1個
  4. 試験的機能(Experimental Features):1個
  5. その他(削除など):1個

1. 正式機能 (Final Features)

506:Scoped Values

JDK 20のJEP 429でインキュベーター機能として提供されてきたScoped Valuesが、プレビューを終えて正式機能となりました。
この機能により、メソッドはスレッド内および子スレッド間でデータを安全かつ効率的に共有できます。特に仮想スレッド(JEP 444)や構造化並行性(JEP 505)と組み合わせることで、メモリ使用量や時間コストを削減できます。

従来、データ共有にはThreadLocalが利用されてきましたが、以下のような課題がありました。

  1. 制限のない可変性(Unconstrained mutability)
    • どこからでもsetできるため、データの更新箇所が追いにくい
  2. 無制限の有効期間(Unbounded lifetime)
    • 値がスレッド終了まで保持されるため、remove忘れによるメモリリークの可能性
  3. 継承コストの高さ(Expensive inheritance)
    • 子スレッドに不要なコピー(親スレッドのスレッドローカル変数)が発生し、メモリを消費

ScopedValueは、以下の特徴があります。スレッド間での不変データの共有を実現し、値のライフサイクルを明確に管理できます。

  • 一方向・一時的なデータ共有:呼び出し元から子メソッド、子スレッドへ不変データを渡す
  • 寿命の明確化ScopedValue.where(...).run(...)の範囲内でのみ有効(終了時に自動廃棄)
  • 軽量な継承StructuredTaskScopeで親スレッドのスコープ付の値を引き継げる(ThreadLocalようにコピーを作る必要がない)
  • 高速アクセス:ローカル変数に近い速度でアクセス可能

ThreadLocalは、過剰に柔軟・寿命が長すぎ・継承が重いという欠点があり、特に仮想スレッド環境では非効率です。
ScopedValueは、不変・寿命が明確・軽量に継承可能という特徴を持ち、より安全かつ効率的なデータ共有を実現する仕組みとして導入されます。

510:Key Derivation Function API

JDK 24のJEP 478でプレビューとして提供された後、正式機能になりました。秘密鍵と他のデータから追加の鍵を導出する暗号アルゴリズムであるKey Derivation Functions (KDFs)の以下のAPIが導入されました。

  • javax.crypto.KDFクラス
  • getInstanceメソッドでKDFを作成・初期化
  • deriveKeyderiveDataメソッドで鍵やデータを導出

RFC 5869で定義された Extract-and-Expand Key Derivation Function(HKDF) や、RFC 9106Argon2 アルゴリズムなどを利用できます。

511:Module Import Declarations

JDK 23のJEP 476、JDK 24のJEP 494でプレビューとして改良された後、正式機能になりました。これにより、モジュールごとにimportが可能になります。
従来のsingle-type-importtype-import-on-demandに加え、今回のmodule importが追加されて、3種類のインポートが可能になりました。

  1. single-type-import:特定のクラスやインターフェースを明示的にインポート
import java.util.List;
  1. type-import-on-demand:パッケージ内のすべての公開型をインポート
import java.util.*;
  1. module import:モジュールがエクスポートするすべてのパッケージを一括でインポート
import module java.base;

java.baseをmodule importしたら、Java SEの機能がほぼ使用できるため便利そうです。
ただし、プロジェクトによっては、インポート宣言を明確化するsingle-type-importを推奨する場合もあるため、チームの方針を確認の上ご使用ください。

512:Compact Source Files and Instance Main Methods

JDK 21のJEP 445でプレビューとして登場し、いくつかの変更が加わって正式機能としてリリースされました。
学習やスクリプト向けに、mainメソッドの簡略化やモジュールインポートの改善がなされました。

主な機能は以下の3つです。

  1. インスタンスmainメソッド
    • 従来のpublic static void main(String[] args)という定型文を省略し、単にvoid main()と書けるようになります。
  2. コンパクトソースファイル
    • クラス宣言なしで直接メソッドやフィールドを記述でき、コンパイラが暗黙的にクラスを生成してくれます。
  3. 基本的なコンソールI/O
    • 新しいjava.lang.IOクラスが追加され、IO.println()IO.readln()で簡単に入出力できます。

例えば「Hello, World!」のコードは、従来は以下のような実装になります。

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}

本機能を適用すると、以下の実装になります。

// 「2. コンパクトソースファイル」により、class宣言省略
void main() {  // 1. インスタンスmainメソッド
  IO.println("Hello, World!");  // 3. 基本的なコンソールI/O
}

スクリプト言語のような軽量さがあり、学習や検証、ドキュメント用には非常に便利な機能です。
ただ、プロジェクトでは従来の形式を利用して、明確に記載する方がチーム開発としてはやりやすいと思います。開発規模やチームのルールを確認して利用してください。

513:Flexible Constructor Bodies

JDK 22のJEP 447でプレビューとして提案された後、正式機能になりました。
コンストラクタの処理で、明示的なコンストラクタ呼び出し(super(...)this(...))の前にも文を記述できるようになります。これにより、スーパークラス呼び出し前に引数検証や軽い初期化を行えます。

従来の制約と問題点として、以下がありました。

  • コンストラクタの最初の文は必ずコンストラクタ呼び出しでなければならない
  • スーパークラスのコンストラクタを呼び出す前に、引数を検証できない
  • 不必要な処理を実行してしまう
  • スーパークラスのコンストラクタがサブクラスのフィールドを初期化前にアクセスしてしまう整合性の問題

新しいコンストラクタ構造としては、コンストラクタ呼び出し前のコードのプロローグと、呼び出し後のコードのエピローグの2つのフェーズに分かれます。
プロローグでは、引数の検証やフィールドの初期化が可能ですが、構築中のオブジェクトへの参照(this)は使用できません。ただし、初期化子を持たないフィールドへの代入は許可されます。
これにより、サブクラスのコンストラクタはスーパークラスのコンストラクタを呼び出す前にフィールドを初期化でき、整合性を保ちながら高速に失敗するコンストラクタを簡潔に記述できるようになります。

コンストラクタ本体にプロローグとエピローグの両方がある場合、以下のように呼び出されます。

class Object {
    Object() {
        // Object constructor body
    }
}

class A extends Object {
    A() {
        // A prologue
        super();
        // A epilogue
    }
}

class B extends A {
    B() {
        // B prologue
        super();
        // B epilogue
    }
}

class C extends B {
    C() {
        // C prologue
        super();
        // C epilogue
    }
}

コンストラクタの呼び出しとプロローグおよびエピローグの実行は以下のようになります。

C prologue
  --> B prologue
    --> A prologue
      --> Object constructor body
    --> A epilogue
  --> B epilogue
C epilogue

プロローグはボトムアップで実行され、エピローグはトップダウンで実行されます。サブクラスの初期化順序を明確に制御でき、整合性を保ちながら柔軟にコンストラクタを書けるようになります。

514:Ahead-of-Time Command-Line Ergonomics

JavaアプリケーションのAhead-of-Time(AOT、事前)キャッシュのプロセスが簡略化できるようになりました。
JDK 24のJEP 483では、AOTキャッシュの作成には2段階の実行が必要でした。まず、recordモードでトレーニング実行を行ってAOT設定ファイルを生成し、次にcreateモードで、その設定からAOTキャッシュを作成します。
JDK 25では、新しいコマンドラインオプション-XX:AOTCacheOutputが導入され、1つのコマンドで両方のモードを実行できるようになります

JDK 24までは、以下のrecordモードとcrateモードの2回のコマンド実行が必要でした。

java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -cp app.jar com.example.App ...
java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot

JDK 25では、以下のコマンドに置き換えることができます。

java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App

JVMは内部的にトレーニング実行とAOTキャッシュ作成を自動的に行い、一時的なAOT設定ファイルは自動削除されます。新しい環境変数JDK_AOT_VM_OPTIONSにより、キャッシュ作成時のみに適用されるオプションを指定できます。
手動での2段階実行も引き続きサポートされているため、ユースケースに合わせて使い分けることができます。

515:Ahead-of-Time Method Profiling

JVMの起動時に、過去のメソッド実行プロファイルを再利用できるようになりました。プロファイルのキャッシュを利用することで、ウォームアップ時間を短縮します。これにより、JITコンパイラはプロファイルの収集を待つことなく、アプリケーション起動直後から最適化済みのネイティブコードを生成できるようになります。

例として、Stream APIの処理時間が 19%短縮(90ms→73ms) されています。キャッシュのサイズ増加は、250キロバイト(約2.5%増)です。

518:JFR Cooperative Sampling

JDK Flight Recorder(JFR)のサンプリング方式が改善され、ネイティブコード実行時の安定性が向上しました。
(JFRは、Java Flight Recorderと記載されることもありますが、本記事ではJEPに記載されているJDK Flight Recorderと表記させていただきました)
JFRは、プログラムスレッドの実行スタックを一定の間隔(20ミリ秒など)でサンプリングしてプロファイルを行っており、JVMクラッシュのリスクが低下し、大規模アプリケーションのプロファイリング精度を高めます。
ただし、ターゲットスレッドがJavaコード(インタープリタ型またはコンパイル型)を実行している場合には有効ですが、ネイティブコードを実行している場合には有効ではありません。ネイティブコードを実行している場合は、既存のアプローチを引き続き使用します。

519:Compact Object Headers

JDK 24のJEP 450でプレビューとして導入されたものが正式機能になりました。
JVMのオブジェクトヘッダーのサイズを、96~128ビットから64ビットに削減することで、ヒープ使用量削減やCPU使用時間短縮、GC回数減少などの効果が確認されています。
(OracleのJDKテストスイート全体を実行したテスト、Amazonの数百の運用サービスでテストを行われました)

コンパクトヘッダーは、以下のコマンドオプションを指定すると有効になります。

java -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders ...

また、ベンチマーク結果によりパフォーマンスが向上することが実証されています。

  • SPECjbb2015ベンチマーク
    • ヒープ使用量:22%削減
    • CPU時間:8%削減
    • GC回数(G1とParallelの両方):15%削減
  • 高並列JSONパーサーベンチマーク
    • 実行時間:10%短縮

520:JFR Method Timing & Tracing

JFRのメソッド単位のタイミング計測やトレースが可能になりました。これにより、パフォーマンス低下の特定やコードの最適化など分析に使用できるようになります。
パフォーマンス低下の特定や最適化に役立ちます。

521:Generational Shenandoah

Shenandoahガベージコレクタ(世代別GC)が正式機能としてリリースされました。ヒープサイズに関係なく低停止時間を維持できます。


2. プレビュー機能 (Preview Features)

正式導入前に最後のフィードバックを募る機能です。利用するには--enable-previewフラグが必要です。

470:PEM Encodings of Cryptographic Objects (Preview)

暗号鍵、証明書、証明書失効リスト(CRL)の暗号化オブジェクトを、広く使用されているPrivacy-Enhanced Mail transport format(PEM転送形式)にエンコード、およびデコードできるAPIを提供します。
java.securityパッケージに以下が導入されます。

  • DEREncodableインターフェース:バイナリエンコード可能な暗号化オブジェクトを表すAPIクラスのインターフェース
  • PEMEncoderクラスPEMDecoderクラス:PEM形式へのエンコード・デコードに使用します。これらのクラスのインスタンスは不変かつ再利用可能です。以前にエンコードまたはデコードされた暗号オブジェクトの情報は保持されません。
  • PEMRecordクラス:Java Platform APIが存在しない暗号オブジェクトのPEMテキストをエンコード・デコードするためのクラス

502:Stable Values (Preview)

一度だけ初期化され、その後は変更されないオブジェクトを扱うStableValue APIがプレビューとして提供されました。
finalのように不変ですが、遅延初期化が可能でスレッド安全で使用できます。

private final StableValue<Logger> logger = StableValue.of(); // <-StableValue宣言

private Logger getLogger() {
    return logger.orElseSet(() -> Logger.create(OrderController.class)); // <-初めて使う時に一度だけ初期化
}

505:Structured Concurrency (Fifth Preview)

JDK 21のJEP 453でプレビューとして提供され、5回目のプレビュー版となります。
並行タスクを構造化して扱う仕組みで、StructuredTaskScopeを使い、複数タスクを1つの作業単位として管理できます。
ScopedValueは、スレッド内で変数を共有できますが、新しい子スレッドには値が引き継がれません。
StructuredTaskScopeは、親スレッドのスコープを子スレッドに安全に引き継ぎます。
キャンセルやエラー処理も簡潔に行え、並列プログラミングの可読性と信頼性が向上します。

507:Primitive Types in Patterns, instanceof, and switch (Third Preview)

instanceofswitch文でプリミティブ型を直接扱えるようになりました。これにより、AI推論や数値解析などでのコードがより簡潔かつ安全に書けるようになります。
AIや数値計算のように大量の数値データを扱うコードでは、型変換の多発、キャストや境界チェックを手動で実装するなど、型変換のバグが出やすいコードを書かないといけませんでした。

従来:

// 型変換
if (obj instanceof Integer)
  x = ((Integer)obj).doubleValue();
else if (obj instanceof Float)
  x = ((Float)obj).doubleValue();

// 型分岐
if (x instanceof Double) handleDouble((Double)x);
else if (x instanceof Float) handleFloat((Float)x);

本機能:

// 型変換
if (obj instanceof double d) x = d;
else if (obj instanceof int i) x = (double) i;

// 型分岐
switch (x) {
  case double d -> handleDouble(d);
  case float f -> handleFloat(f);
}

型変換は、キャストやラッパークラスを意識せずに、安全に共通のdoubleへ変換可能となり、型判定とキャストを一行で安全に書けるようになります。また、型分岐は、switchによる分岐を書けるようになります。


3. インキュベーター機能 (Incubator Features)

まだ開発の初期段階にある実験的なAPIです。将来大きく変更される可能性があります。

508:Vector API (Tenth Incubator)

ベクトル演算を表現するAPIが、JDK 16のJEP 338以降継続的に改良され、今回で10回目のインキュベーターリリースとなりました。
サポートされているCPU上で最適なベクトル命令にコンパイルされ、AI推論や数値計算を高速化します。特に、Float16の自動ベクター化は、機械学習や深層学習において性能を向上させる上で大きな意味を持つ変更になります。


4. 試験的機能 (Experimental Features)

特にリスクが高く不確実な、研究室レベルの実験的機能です。

509:JFR CPU-Time Profiling (Experimental)

JFRに、CPU時間のプロファイリング情報を取得できる機能が追加されました(Linux限定)。
より正確なCPUの使用時間分析が可能となり、パフォーマンスボトルネックの特定が行えるようになります。


5. その他(削除など)

503:Remove the 32-bit x86 Port

JDK 24のJEP 479JEP 501で、Windows向け32ビットx86ポートの削除とLinux向け32ビットx86ポートの非推奨となり、32ビット廃止の動きがありました。そして、ついにLinux向け32ビットx86ポートが削除されました。
ビルドやテストを簡素化し、今後の大規模な機能の統合に向けてコードのクリーンアップに繋げていく動きになりそうです。


まとめ

Java 25は、言語の使いやすさを向上させる機能から、JVMのパフォーマンスを改善する機能まで、幅広いアップデートが実施されました。

個人的には、JEP 507(Primitive Types in Patterns, instanceof, and switch (Third Preview))JEP 508(Vector API (Tenth Incubator))で、AIや数値解析の利用に向けた機能も改良が進められているので期待しています。
また、これまであまり取り上げられることのなかった JFR 関連の改善が含まれているため、別途JFRについても調べていこうと思います。

注意点

本記事の内容は私が調査した情報に基づいており、正確性を保証するものではありません。
また、掲載したソースコードはサンプルになります。
本記事の内容を利用することで発生するいかなる損害や不利益について、当社は一切の責任を負いませんので自己の責任においてご利用ください。

Discussion