Java 27が2026/9/15にリリースされました。
Java 27 / JDK 27: General Availability - jdk-dev - openjdk.org
Oracle Releases Java 27
The Arrival of Java 27
非LTSで、Java 27では前回から引き継いだプレビューが多くほとんど変更はありません。
TLS1.3の鍵交換に耐量子ハイブリッド方式を追加するJEP 527が、10月から来年後半にかけてJava 25からJava 8までのLTSに順次バックポートされる、というのが注目情報ですかね。
Post-Quantum Cryptography in Long-Term Support JDK Releases | java
今回はBlender+Qwen3-TTSで自動生成した解説動画をいくつかつけています。(ぼくはしゃべってません)
JDKをインストールせずに言語やライブラリの新機能を試したい場合にはJava Playgroundが便利です。
https://dev.java/playground/
イベント
福岡では9/15にLINEヤフー博多オフィスで「Kotlinによる関数型プログラミング入門」出版記念会とあわせて行います。(終了しました)
「Kotlinによる関数型プログラミング入門」出版記念とJava 27 at 福岡 - connpass
資料
詳細はこちら
JDK 27 Release Notes
Java SE 27 Platform JSR 402
OpenJDK JDK 27 GA Release
APIドキュメントはこちら
Overview (Java SE 27 & JDK 27)
追加されたAPIまとめはこちら
https://docs.oracle.com/en/java/javase/27/docs/api/new-list.html
ディストリビューション
MacやLinuxでのインストールにはSDKMAN!をお勧めします。
Oracle OpenJDK以外に無償で商用利用できるディストリビューションとしては、次のようなものがあります。
※ Microsoft Build of OpenJDK、GraalVMは非LTSバージョンのリリースはありません
どのディストリビューションを使えばいいかわからないときは、とりあえずEclipse Temurinが無難です。
アップデートは、通例であれば10月に27.0.1が、1月に27.0.2がリリースされることになりますが、頻度がかわる可能性があります。
Oracle JDKの無償ライセンスであるNFTCは次バージョンのJava 28リリースまでで、それ以降のアップデートでは有償のOTNに切り替わるので注意が必要です。
開発組織
関わった開発組織は、こんな感じになってます。日本企業ではNTT DataとFujitsuが貢献を続けています。今回NTT DataはGoogleよりも大きいですね。

JEP
大きめの変更はJEPでまとまっています。
https://openjdk.org/projects/jdk/27/
今回は9個のJEPが取り込まれました。正式採用は4個です。プレビューからの正式化もありません。プレビューは前回からの5個で、新たに入ったものはありません。
今回は次の5つのカテゴリにまとめてます
523: Make G1 the Default Garbage Collector in All Environments
527: Post-Quantum Hybrid Key Exchange for TLS 1.3
531: Lazy Constants (Third Preview)
532: Primitive Types in Patterns, instanceof, and switch(Fifth Preview)
533: Structured Concurrency (Seventh Preview)
534: Compact Object Headers by Default
536: JFR In-Process Data Redaction
537: Vector API (Twelfth Incubator)
538: PEM Encodings of Cryptographic Objects (Third Preview)
API
APIの変更としてはセキュリティ系を除いて3つのJEPがあります。新しく入っものはありません。
531: Lazy Constants (Third Preview)
533: Structured Concurrency (Seventh Preview)
537: Vector API (Twelfth Incubator)
小さいもの
JEPになっていないAPI変更で、開発に影響しそうなものとしては双曲線関数の逆関数があります。
acosh / asinh / atanh
双曲線関数のcosやsin、tanの逆関数です。
531: Lazy Constants (Third Preview)
Java 25でStable Valueだった機能がメソッドが整理されLazy Constantsとして3rd Previewになりました。
Javaでは、不変な値を保持する仕組みとしてfinalがあります。
final Logger logger = Logger.create();
しかし、クラスやインスタンスの初期化時にすべての不変値を初期化してしまうと、起動が遅くなったりネットやファイルへのアクセスが集中することにもなります。
そこで、値が必要になったときに初期化したいということが多くあります。
そのような場合、アクセッサを介して値を得るようにすることで、遅延初期化を実現します。
private Logger logger;
Logger getLogger() {
if (logger == null) {
Logger.create();
}
return logger;
}
けれども、このようにするとフィールドからfinalが外れることでJVMでの最適化が効きにくくなります。また、マルチスレッドを考慮すると少し複雑なコードが必要になります。もしくは、マルチスレッドで初期化が多重に行われても問題ないかどうか判断して、実質的な問題がなければそのままスレッドセーフではないコードを使うことになります。
そういった場合に使えるのが今回導入されるLazyConstantです。
final LazyConstant<Logger> logger = LazyConstant.of(() -> Logger.create());
logger.get().info("started");
...
logger.get().info("finish");
このときofメソッドで指定した初期化コードは1度だけしか呼び出されないことがLazyConstantによって保証され、スレッドセーフになります。また、JVMでの最適化も行われるようになります。
不変値のコレクションを扱いたいときはofLazyが使えます。
final List<Connection> pool = List.ofLazy(10, idx -> new Connection(idx + "th connection");
こうするとpool.get(3)などとしてリストにアクセスすると、初回にそのインデックスに対応する値が初期化されるようになります。
LazyConstantはプレビューなので、関連機能を使うときには--enable-previewが必要です。
533: Structured Concurrency (Seventh Preview)
Java 19でIncubatorとして含まれていましたが、Java 26で6th Previewになり、Java 27では変更なく6th Previewになりました。
並列処理では、複数の処理を実行するときに、両方が終われば正常終了とか、どちらか片方が終われば終了だとか、どちらか一方でも例外が発生したら終了だとか、同時に行う処理で連動することがあります。
しかし、これを既存のjoinやwaitなどで制御しようとすると、実際にはjoinからwaitへのGo Toを書くようなコードになって、処理が追えなくなります。
そこで導入されるのが構造化並列性といいます。
こんな感じ。詳しくはあとで書きます!(Java 19のときから言ってる・・・)
Response handle() throws InterruptedException {
try (var scope = StructuredTaskScope.open()) {
Subtask<String> user = scope.fork(() -> findUser());
Subtask<Integer> order = scope.fork(() -> fetchOrder());
scope.join() // Join both forks, propagatiton exceptions
// Both subtasks have succeeded, so compose their results
return new Response(user.get(), order.get());
}
}
SubtaskはSupplierを継承しているので、Supplierとして扱うほうがいいかもしれません。
537: Vector API (Twelfth Incubator)
AVX命令のような、複数のデータに対する計算を同時に行う命令をJavaから利用できるようになります。
使うためには実行時やコンパイル時に--add-modules jdk.incubator.vectorをつける必要があります。
Java 16でインキュベータとして導入されたPanamaプロジェクトの残る片割れですが、12th Incubatorになりました。Project Valhallaのvalue classを使いたいようで、関連JEPがpreviewになるまではIncubatorのままということです。
基本的な使い方は次のようになります。
import jdk.incubator.vector.*;
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_256;
void vectorComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i += SPECIES.length()) { // SPECIES.length() = 256bit / 32bit -> 8
VectorMask<Float> m = SPECIES.indexInRange(i, a.length); // 端数がマスクされる
// a.lengthが11でiが8のとき最初の3つしか要素がないので [TTT.....]
// FloatVector va, vb, vc;
FloatVector va = FloatVector.fromArray(SPECIES, a, i, m);
FloatVector vb = FloatVector.fromArray(SPECIES, b, i, m);
FloatVector vc = va.mul(va).
add(vb.mul(vb)).
neg();
vc.intoArray(c, i, m);
}
}
言語機能
言語機能の変更としても新しいものはなく正式化されたものもありません。
532: Primitive Types in Patterns, instanceof, and switch(Fifth Preview)
532: Primitive Types in Patterns, instanceof, and switch(Fifth Preview)
Java 23でプレビューとして入りましたが、機能的な変更なく5thプレビューになりました。
instanceof
instanceofでプリミティブを使うとき、値が欠落しないかどうかが判定基準になります。
jshell> int i = 128
i ==> 128
jshell> i instanceof byte
$2 ==> false
jshell> i = 127
i ==> 127
jshell> i instanceof byte
$4 ==> true
実数型を整数型で判定するときは、精度落ちするかどうかが判定されます。
jshell> double d = 1
d ==> 1.0
jshell> d instanceof int
$2 ==> true
jshell> d = 1.2
d ==> 1.2
jshell> d instanceof int
$4 ==> false
ただし、ラッパークラスのオブジェクトの場合はその基本型のときだけtrueになります。
jshell> Long num = 123L
num ==> 123
jshell> num instanceof int
| エラー:
| 不適合な型: java.lang.Longをintに変換できません:
| num instanceof int
| ^-^
jshell> num instanceof long
$7 ==> true
そしてパターンマッチとして使えるわけですね。
jshell> long num = 123
num ==> 123
jshell> var out = new ByteArrayOutputStream()
out ==>
jshell> if (num instanceof byte b) out.write(b)
jshell> out.toByteArray()
$21 ==> byte[1] { 123 }
jshell> num = 1234
num ==> 1234
jshell> if (num instanceof byte b) out.write(b)
jshell> out.toByteArray()
$24 ==> byte[1] { 123 }
switch
このパターンマッチがswitchでも使えるということなんですけど、定数パターンもあるので、switchですべての型が使えるようになったということになります。
jshell> long num = 1234
num ==> 1234
jshell> switch (num) { case int n -> "いんと"; default -> "それ以外";}
$25 ==> "いんと"
jshell> num = 30_0000_0000L
num ==> 3000000000
jshell> switch (num) { case int n -> "いんと"; default -> "それ以外";}
$27 ==> "それ以外"
if式のようなこともできますね。
boolean flag = isFoo();
var s = switch (flag) {
case true -> "たった";
case false -> "おりた";
}
JVM
JVMの変更として、2つJEPが導入されています。
523: Make G1 the Default Garbage Collector in All Environments
534: Compact Object Headers by Default
523: Make G1 the Default Garbage Collector in All Environments
いままでも基本的にはG1 GCがデフォルトでしたが、シングルコアや1792MB未満のメモリの場合にはSerial GCが選択されていました。
G1 GCの改良により、Serial GCより優れたGCになったため、Serial GCを使う理由がなくなりました。
リソースが限られた環境でもG1 GCがデフォルトになり、GCの挙動がわかりやすくなります。
534: Compact Object Headers by Default
Java 25で正式採用された、オブジェクトヘッダに12-16バイトを使っていたものを8バイトに短縮するというCompact Object Headersがデフォルトになります。
Java 25新機能まとめ / Compact Object Headers
Security
セキュリティ、暗号関係では次のJEPが導入されています。
527: Post-Quantum Hybrid Key Exchange for TLS 1.3
538: PEM Encodings of Cryptographic Objects (Third Preview)
527: Post-Quantum Hybrid Key Exchange for TLS 1.3
TLS1.3の鍵交換に耐量子ハイブリッド方式を追加します。
現状で暗号を解読できる量子コンピュータはありませんが、国家機密などの年月がたっても利用価値が高い情報は、いまのうちからデータを集めて、解読可能になったときに読み取るという攻撃が考えられます。
そのため、早いうちからの対策が必要です。
冒頭でも書いたように10月から来年後半にかけてJava 25からJava 8までのLTSに順次バックポートされます。
| バージョン | 時期 |
|---|---|
| Java 25 | 2026年10月 |
| Java 21&17 | 2027年前半 |
| Java 11&8 | 2027年後半 |
Post-Quantum Cryptography in Long-Term Support JDK Releases | java
538: PEM Encodings of Cryptographic Objects (Third Preview)
暗号鍵や証明書などの暗号オブジェクトを送受信するための表現形式として、Privacy-Enhanced Mail(PEM)形式がよく使われています。PEM形式は名前のとおり、メール用に設計されましたが、他の用途にも使われるようになっています。
このJEPで、PEM形式へのエンコードやデコードを行うAPIを定義します。
ツール
ツール関連ではJVM Flight Recorder関連の変更が3つ入っています。
536: JFR In-Process Data Redaction
536: JFR In-Process Data Redaction
JDK Flight Recorderでは、パスワードやトークン、APIキーなどの環境変数も記録してしまいます。
これらの機密情報をデフォルトで[REDACTED]という文字列に置き換えます。
機密情報として扱うキーはデフォルトで*api*key*や*passwork*などにあてはまるものです。
XX:FlightRecorderOptions:redact-argumentやXX:FlightRecorderOptions:redact-keyを指定することで、機密情報として扱う引数や環境変数を指定します。+で始めるとデフォルトのキーに追加、noneにするとData Redactionを無効にします。




