Java

Java 24(JDK 24)の新機能24件のJEPと現在地|LTSではない版の移行先と実機で確かめた挙動

Java 24(JDK 24)の新機能24件のJEPと現在地|LTSではない版の移行先と実機で確かめた挙動

Java 24(JDK 24)は2025年3月18日にGAとなった非LTSのフィーチャーリリースです。「java 24 lts」で検索されることがありますが、24はLTSではありません。OracleのPremier Supportは2025年9月に終わり、アップデートは2025年7月15日の24.0.2が最後でした。本記事では、JDK 24に入った24件のJEPがJava 25・26・27でどうなったかを一覧にし、Stream Gatherersや仮想スレッドのピン留め解消、AOTキャッシュをJDK 21〜27で実際に動かした結果をもとに、24から移る先の選び方まで整理します。最新版のJava 27はJava 27の非LTS運用とG1・オブジェクトヘッダ既定化の影響で扱っています。

まとめ:Java 24の要点

  • Java 24はLTSではありません。GAは2025年3月18日、OracleのPremier Supportは2025年9月で終了し、Extended Supportはありません。最終アップデートは24.0.2(2025年7月15日)です。
  • 24件のJEPのうち14件は正式機能として入り、10件はプレビュー・インキュベーター・実験的機能でした。プレビューだったスコープ付き値・モジュールインポート宣言・柔軟なコンストラクタ本体・シンプルなソースファイルは、Java 25で正式になっています。
  • 構造化並行性とプリミティブ型のパターンは、Java 27でもまだプレビューです。構造化並行性はJDK 28(2027年3月予定)に正式機能として統合済みです。
  • synchronizedの中で待っても仮想スレッドがキャリアを占有しなくなりました(JEP 491)。実測では同じコードがJDK 21で14,228ミリ秒、JDK 24で372ミリ秒でした。
  • 移行で止まりやすいのはSecurity Managerの無効化とZGCの非世代モード削除です。-Djava.security.manager=allow はJDK 24で起動エラーになり、-XX:-ZGenerational は26以降で起動できなくなります。
  • 今24を使っているなら、移行先はJava 25 LTSが第一候補です。24でコンパイルしたプレビュー機能入りのクラスは25では動かないため、再コンパイルが必要です。

Java 24のサポート期限と最終アップデート

非LTSのJDKは、次の版が出る半年後に更新が止まります。OracleのJava SE Support Roadmapでは、22〜24の非LTSはPremier Supportがそれぞれ次の9月または3月までで、Extended Supportは「Not Available」です。24の場合は2025年9月が期限でした。

アップデートは2回だけです。JDK 24のリリースノートに載っているのは24.0.1(2025年4月15日)と24.0.2(2025年7月15日)で、Adoptium(Eclipse Temurin)のリリース一覧も jdk-24.0.2+12 が最後です。2025年10月以降に見つかった脆弱性の修正は、24には提供されていません。

版 区分 GA Oracle Premier Support Extended Support
Java 21 LTS 2023年9月 2028年9月 2031年9月
Java 24 非LTS 2025年3月18日 2025年9月 なし
Java 25 LTS 2025年9月16日 2030年9月 2033年9月
Java 26 非LTS 2026年3月17日 2026年9月 なし
Java 27 非LTS 2026年9月15日 2027年3月 なし

24のクラスファイルのメジャーバージョンは68です(javap -v で major version: 68 を確認)。古いバイナリがどの版でビルドされたかを調べるときの目印になります。OracleとOpenJDKビルドの無償範囲の違いはOpenJDKの商用利用とサポート期限にまとめています。

JDK 24の24件のJEPと後継版での扱い

OpenJDKのJDK 24プロジェクトページに載るJEPは24件で、そのうち10件はプレビュー・インキュベーター・実験的機能でした。JEP(JDK Enhancement Proposal)は、JDKへの機能追加や変更を提案・管理する文書です。番号は提案を識別するもので、すべての提案が正式機能になるとは限りません。下表の「その後」は、JDK 25・26・27・28のプロジェクトページと各JEPのステータスで確認した2026年10月時点の状態です。

JEP 内容 24での段階 その後
404 世代別Shenandoah 実験的 25で製品機能(521)、28で既定化予定(535)
450 コンパクトオブジェクトヘッダ 実験的 25で製品機能(519)、27で既定(534)
472 JNI利用制限の準備 正式 警告のまま
475 G1のバリア展開の後段化 正式 -
478 鍵導出関数(KDF)API プレビュー 25で正式(510)
479 Windows 32bit x86ポート削除 正式 -
483 AOTクラスロード&リンク 正式 25で作成手順を簡略化(514)、メソッドプロファイルを保存(515)
484 Class-File API 正式 -
485 Stream Gatherers 正式 -
486 Security Managerの恒久無効化 正式 API本体は将来削除
487 スコープ付き値 第4プレビュー 25で正式(506)
488 プリミティブ型のパターン 第2プレビュー 27でも第5プレビュー(532)
489 Vector API 第9インキュベーター 27で第12インキュベーター(537)
490 ZGCの非世代モード削除 正式 26でフラグ自体が起動エラー
491 synchronizedでピン留めしない仮想スレッド 正式 -
492 柔軟なコンストラクタ本体 第3プレビュー 25で正式(513)
493 JMODなしのjlink 正式(ビルド時に選択) -
494 モジュールインポート宣言 第2プレビュー 25で正式(511)
495 シンプルなソースファイルとインスタンスmain 第4プレビュー 25で正式(512)
496 ML-KEM(耐量子の鍵カプセル化) 正式 27でTLS 1.3のハイブリッド鍵交換(527)
497 ML-DSA(耐量子の署名) 正式 -
498 Unsafeのメモリアクセスで警告 正式 27でも警告のまま(実測)
499 構造化並行性 第4プレビュー 27で第7プレビュー(533)、28で正式化予定(543)
501 32bit x86ポートの非推奨化 正式 25で削除(503)

表の括弧内は後継のJEP番号です。JDK 28は2027年3月GA予定で、構造化並行性の正式版(JEP 543)は2026年10月時点でStatusが「Integrated」です。

Java 24の正式機能と実行結果

ここからのコードは、Eclipse Temurin 24.0.2をIntel Core i9-9880H(8コア16スレッド)のmacOSで動かした結果です。プレビュー用のフラグは付けていません。

Stream Gatherers(JEP 485)の中間操作と出力例

Stream.gather は、map や filter では書けなかった「固定長でまとめる」「累積しながら流す」といった中間操作を差し込むAPIです。標準で用意された Gatherers の5つを試しました。

List<Integer> sales = List.of(120, 80, 150, 90, 200, 60, 170);
sales.stream().gather(Gatherers.windowFixed(3)).toList();
// [[120, 80, 150], [90, 200, 60], [170]]
sales.stream().gather(Gatherers.windowSliding(3))
     .map(w -> w.stream().mapToInt(Integer::intValue).sum() / w.size()).toList();
// [116, 106, 146, 116, 143]  3件移動平均
sales.stream().gather(Gatherers.scan(() -> 0, Integer::sum)).toList();
// [120, 200, 350, 440, 640, 700, 870]  累計
sales.stream().gather(Gatherers.fold(() -> 0, Math::max)).toList();
// [200]
Stream.of("a", "b", "c", "d", "e", "f", "g", "h")
      .gather(Gatherers.mapConcurrent(4, s -> {
          try {
              Thread.sleep(200);
          } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
              throw new RuntimeException(e);
          }
          return s.toUpperCase();
      }))
      .toList();
// [A, B, C, D, E, F, G, H]  753 ms

mapConcurrent は仮想スレッドで最大4件を同時に処理し、結果の順序は入力どおりに保たれます。200ミリ秒かかる処理8件が753ミリ秒で終わり、逐次実行なら1,600ミリ秒かかる計算です。並列ストリームと違い同時実行数を自分で決められるので、外部APIへの同時接続数を絞りたい場面に向きます。ラムダとStream APIの使い分けはJavaラムダ式とStream APIの使いどころで扱っています。

synchronizedでの仮想スレッドのピン留め解消(JEP 491)

Java 21の仮想スレッドは、synchronized ブロックの中でブロックするとキャリアスレッド(OSスレッド)を手放せず、他の仮想スレッドが待たされました。JEP 491でこの制約が外れています。1,000本の仮想スレッドがそれぞれ別のロックを取り、中で100ミリ秒スリープするコードを各版で実行しました。

try (var ex = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 1000; i++) {
        Object lock = new Object();
        ex.submit(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
    }
}
JDK 完了までの時間
21.0.13(LTS) 14,228 ms
24.0.2 372 ms
25.0.4.1(LTS) 366 ms
27 342 ms

21ではキャリアが16本しかないため、スリープ中の仮想スレッドがキャリアを占有して順番待ちになります。24以降は全スレッドがほぼ同時に眠れます。synchronized を ReentrantLock に書き換える作業は、ピン留め回避だけが目的なら24以降では不要です。

ただし、ピン留めがすべて消えたわけではありません。JEP 491は、ネイティブメソッドやFFM API経由のネイティブコードからJavaへ戻ってブロックする場合や、クラス初期化子の中でブロックする場合は引き続きピン留めされると明記しています。別のスレッドによるクラス初期化の完了を待つケースは、JDK 26(JDK-8369238)で多くの場合キャリアを手放すよう改善されました。残ったケースはJFRの jdk.VirtualThreadPinned イベントで検出でき、21で使えた jdk.tracePinnedThreads システムプロパティは不要になりました。仮想スレッドの基本はJava仮想スレッドとProject Loom入門を参照してください。

耐量子暗号ML-KEM・ML-DSA(JEP 496・497)

NISTが2024年に標準化したFIPS 203(ML-KEM)とFIPS 204(ML-DSA)が、追加ライブラリなしで使えるようになりました。鍵カプセル化は javax.crypto.KEM、署名は既存の Signature で扱います。

KeyPair kp = KeyPairGenerator.getInstance("ML-KEM").generateKeyPair();
KEM kem = KEM.getInstance("ML-KEM");
KEM.Encapsulated enc = kem.newEncapsulator(kp.getPublic()).encapsulate();
SecretKey k2 = kem.newDecapsulator(kp.getPrivate()).decapsulate(enc.encapsulation());
// 送信側の enc.key() と受信側の k2 が同じ32バイトの共有鍵になる
パラメータセット 実測サイズ
ML-KEM-512 公開鍵 822バイト
ML-KEM-768(既定) 公開鍵 1,206バイト・暗号文 1,088バイト
ML-KEM-1024 公開鍵 1,590バイト
ML-DSA-44 署名 2,420バイト
ML-DSA-65(既定) 署名 3,309バイト
ML-DSA-87 署名 4,627バイト

公開鍵はX.509エンコード後の長さです。getInstance("ML-KEM") のように名前だけを渡すと、ML-KEM-768とML-DSA-65が選ばれました。ECDSAの署名が数十バイトなのに比べ、ML-DSAは数キロバイトになります。証明書やトークンに載せるならサイズの見積もりが要ります。Java 27では、このML-KEMを使うTLS 1.3のハイブリッド鍵交換(X25519MLKEM768 など)がJEP 527で入りました。耐量子暗号の全体像は耐量子暗号とML-KEMの仕組みにあります。

AOTクラスロード&リンク(JEP 483)の起動時間と制約

1回目の実行(トレーニング)で読み込んだクラスを記録し、ロードとリンクを済ませた状態をキャッシュファイルに保存します。JDK 24では2段階で作ります。

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

Stream・java.time・ロギング・XMLパーサーを少しずつ使う小さなアプリで、10回ずつ起動した中央値はキャッシュなし719ミリ秒、キャッシュあり348ミリ秒でした。キャッシュファイルは約14MBです。測定では各条件で12回起動し、最初の2回を除いた10回の中央値を使いました。条件が合わないとキャッシュは作れないか、使われません。

  • クラスパスにディレクトリを含めると作れない。-cp classes のままでは作成段階が Error occurred during CDS dumping と Cannot have non-empty directory in paths で失敗します。JEP 483も「Class paths must contain only JAR files」と定めています。
  • クラスパスが変わると警告を出してキャッシュなしで起動する。同じ中身のJARを別名にすると shared class paths mismatch の警告だけ出て、キャッシュなしで起動します。-XX:AOTMode=on を付ければ、無効なときに起動を止められます。
  • JDKの版をまたげない。24で作ったキャッシュを25で読むと The AOT cache version 0x12 does not match the required version 0x13. になります。JDKを上げたらトレーニングからやり直します。

Java 25では -XX:AOTCacheOutput=app.aot の1回でキャッシュを作れるようになりました(JEP 514)。24でこのオプションを渡すと Unrecognized VM option で起動しません。

Class-File APIと@since 24のAPI(JEP 484)

java.lang.classfile パッケージで、ASMなどの外部ライブラリなしに .class ファイルを読み書きできます。先ほどのクラスを読ませると、メジャーバージョンとメソッド一覧が取れました。

ClassModel cm = ClassFile.of().parse(Files.readAllBytes(Path.of(args[0])));
System.out.println(cm.thisClass().asInternalName() + " major=" + cm.majorVersion());
for (MethodModel m : cm.methods()) {
    System.out.println("  " + m.methodName().stringValue() + m.methodType().stringValue());
}
// GatherersDemo major=68
//   main([Ljava/lang/String;)V ...

JDK 24のAPI仕様のNew API一覧で「24」と付くもののうち、Class-File APIとStream Gatherers以外では Reader.of(CharSequence)、Process.waitFor(Duration)、仮想スレッドのスケジューラを監視する jdk.management.VirtualThreadSchedulerMXBean、ML-KEM・ML-DSAのパラメータを指す NamedParameterSpec.ML_KEM_768 などの定数が実務で使えます。このうちReader.of、Process.waitFor(Duration)、VirtualThreadSchedulerMXBeanを使うコードをJDK 21でコンパイルすると、いずれも cannot find symbol などのエラーになりました。

Java 24で起動しなくなる・警告が出る変更

Security Managerの恒久無効化(JEP 486)

17で非推奨になったSecurity Managerは、24で有効にできなくなりました。-Djava.security.manager=allow を付けると、起動の時点で止まります。

Error occurred during initialization of VM
java.lang.Error: A command line option has attempted to allow or enable the Security Manager. Enabling a Security Manager is not supported.

実行中に System.setSecurityManager を呼ぶと UnsupportedOperationException: Setting a Security Manager is not supported が投げられます。System.getSecurityManager() は常に null です。起動スクリプトに java.security.manager の指定が残っていないか、移行前に確認してください。

ZGCの非世代モード削除(JEP 490)

24から、ZGCは世代別モードだけになりました。-XX:+UseZGC -XX:-ZGenerational を各版で試すと、扱いが2段階で変わります。

  • 24と25:Ignoring option ZGenerational; support was removed in 24.0 の警告を出し、世代別ZGCで起動する
  • 26と27:Unrecognized VM option 'ZGenerational' で起動に失敗する

24や25では警告だけで動くため見落とされがちですが、26以降へ上げた時点で起動しなくなります。ZGC全般はZGCの仕組みとG1GCとの違いで解説しています。

sun.misc.Unsafeのメモリアクセス警告(JEP 498)

Unsafe.allocateMemory などを初めて呼んだ時点で、4行の警告が標準エラーに出ます。

WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::allocateMemory has been called by UnsafeDemo (file:...)
WARNING: Please consider reporting this to the maintainers of class UnsafeDemo
WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release

呼び出し元のクラスとJARが表示されるので、どのライブラリが使っているかはここで特定できます。--sun-misc-unsafe-memory-access=deny を付けると UnsupportedOperationException: allocateMemory で止まるため、将来の削除に備えた検証に使えます。JEP 498は「JDK 26以降で例外を投げる」予定と書いていますが、26.0.2.1とJava 27でも既定は警告のままでした。

このほか、JNIでネイティブライブラリを読み込むと警告が出るようになりました(JEP 472)。クラスパス上のコードには --enable-native-access=ALL-UNNAMED を指定します。名前付きモジュールには、--enable-native-access=対象モジュール名 で個別にネイティブアクセスを許可します。

Java 24のプレビュー機能の正式化状況と再コンパイル

JDK 24でプレビューだった5つの言語機能・APIを、各版で --enable-preview を付けずにコンパイルしました。

機能 24 25 26 27
スコープ付き値 エラー 通る 通る 通る
モジュールインポート宣言 エラー 通る 通る 通る
柔軟なコンストラクタ本体 エラー 通る 通る 通る
クラス宣言なしの void main() エラー 通る 通る 通る
プリミティブ型のパターン エラー エラー エラー エラー

24でのエラーは error: module imports are a preview feature and are disabled by default. の形で、機能ごとに名前が変わります。柔軟なコンストラクタ本体は、super(...) の前に引数を検査できる機能です。

class Positive {
    Positive(int v) {
        if (v < 1) throw new IllegalArgumentException("positive value required");
    }
}

class Port extends Positive {
    Port(int v) {
        if (v < 1 || v > 65535) throw new IllegalArgumentException("port out of range: " + v);
        super(v);
    }
}

注意したいのは、24で --enable-preview を付けてコンパイルしたクラスです。25で --enable-preview を付けて実行しても、次のエラーで読み込めません。

java.lang.UnsupportedClassVersionError: FlexCtor (class file version 68.65535) was compiled with preview features that are unsupported. This version of the Java Runtime only recognizes preview features for class file version 69.65535

プレビュー機能を使ったクラスは、実行するJDKと同じ版でしか動きません。24でプレビュー機能を試していたコードは、25に上げるときにソースから再コンパイルが必要です。

実験的機能も同じ傾向です。コンパクトオブジェクトヘッダ(-XX:+UseCompactObjectHeaders)と世代別Shenandoahは、24では -XX:+UnlockExperimentalVMOptions がないと起動エラーになり、25ではそのまま起動しました。構造化並行性の25〜27でのAPI変更はJava 26の新機能10個のJEPと現在地で追っています。

Java 24からの移行先の選び方

24で動いているシステムは、Java 25 LTSへ移すのが基本です。24で正式になった機能は25でもそのまま使え、25のPremier Supportは2030年9月まであります。24から上げるときに確認するのは、上で挙げたプレビュー機能の再コンパイルと、ライブラリやビルドツールが25に対応しているかです。21と25の差分はJava 21と25の違いに実測付きでまとめています。

Java 26は2026年9月にPremier Supportが終わっており、移行先には向きません。27はJEP 534でコンパクトオブジェクトヘッダが既定になり、メモリが減る効果を得られますが、2027年3月に28が出れば更新が止まります。半年ごとにJDKを上げるCIとテストの体制がないなら、27は選ばない方が安全です。

21以前から一気に上げる場合は、24で入ったSecurity Managerの無効化とUnsafe警告が21と25の間に挟まります。8や11から段階的に上げる手順はJava近代化の進め方で扱っています。基幹システムのJava移行を外部に任せる場合は、issohのシステムマイグレーション・リプレイスでも相談を受けています。

よくある質問

Java 24はLTS(長期サポート)ですか?

いいえ。Java 24は非LTSで、OracleのPremier Supportは2025年9月に終わり、Extended Supportはありません。前後のLTSはJava 21とJava 25です。

Java 24のサポート期限と最終バージョンは?

サポート期限は2025年9月で、最終アップデートは2025年7月15日公開の24.0.2です。Eclipse Temurinも jdk-24.0.2+12 が最後のビルドで、以降のセキュリティ修正はありません。

Java 24(JDK 24)は今でもダウンロードできますか?

できます。OracleのJava SE 24 Archive Downloadsとjdk.java.netのアーカイブに24.0.2まで残っています。セキュリティ修正が止まった版なので、古いアプリの再現確認などの検証用途に限ってください。

Java 24とJava 25の違いは何ですか?

最大の違いはサポート区分で、25はLTSです。機能面では、24でプレビューだったスコープ付き値・モジュールインポート宣言・柔軟なコンストラクタ本体・シンプルなソースファイルが25で正式になり、AOTキャッシュも1回のコマンドで作れるようになりました。

JEPとは何ですか?

JEP(JDK Enhancement Proposal)は、JDKへの機能追加や変更を提案・管理する文書です。提案ごとに番号が振られます。プレビューやインキュベーターを経る提案もありますが、必須の段階ではなく、正式化せず撤回される場合もあります。JDK 24に24件のJEPが入ったのは偶然で、版番号とは関係ありません。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.11.09 テックブログ エディオン不正アクセス第2報:カード番号の対象確認とログ・決済画面の改ざん対策
  2. 2026.11.09 テックブログ LANSCOPE不正アクセス第2報:製品への影響と偽連絡の確認、停止中のライセンス認証の窓口
  3. 2026.11.10 テックブログ Claude Fable 5.2とは:料金・破壊的変更4点とFable 5.1からの移行手順【2026年11月】
  4. 2026.11.09 テックブログ ステップゴルフ不正アクセス:口座情報の対象確認と偽連絡・引き落としの注意点
  5. 2026.11.10 テックブログ ニトリの情報漏洩:最大3,762万件の対象確認となりすまし連絡の見分け方

RELATED POSTS 関連記事

目次