2020年9月15日に、Javaの最新版となるJava 15およびその開発ツールキットであるOpenJDK 15がリリースされた。そこで今回は、Java 15に追加されたおもな新機能をまとめて紹介したい。なお、現在のJavaのリリースサイクルや新機能の導入プロセスについては本連載の第1回の解説を参照していただきたい。
Java 15 / JDK 15について

Java 15の参照実装であるJDK 15については、OpenJDKプロジェクトの次のページにまとめられている。

JDK 15 | OpenJDK Project

これを見てもわかるように、Java 15には全部で14個のJEP(JDK Enhancement Proposal)が含まれており、その内訳は、JVMに関する新機能が2個、言語およびAPIに関する新機能が8個、既存機能の削除または非推奨化が4個となっている。

JCP(Java Community Process)によるJava 15仕様はJSR 390として規定されており、2020年9月8日にリリースされている。

JSR 390: Java SE 15

実際に利用可能なJDK 15実装は、OpenJDK 15をベースにして各ディストリビュータが提供を開始している。Oracleによる無償版のビルドは下記サイトからダウンロードできる。

JDK 15 GA Release | jdk.java.net

いろいろなベンダーのJDKを試してみたいという場合は、第2回で取り上げたSDKMANおよびShogunの利用をお勧めしたい。

さて今回は、JEPとして提案されたものを中心にJava 15の新機能を紹介する。
ZGCとShenandoah GCが正式版に昇格

まずJVMの新機能だが、Experimental(実験的機能)扱いだった次の2つのGC(ガーベジコレクタ)が正式版に昇格した。

JEP 377: ZGC: A Scalable Low-Latency GarbageCollector (Production)
JEP 379: Shenandoah: A Low-Pause-Time Garbage Collector (Production)

「ZGC」Java 11から搭載されている、数TBオーダーの巨大なヒープサイズも対応したスケーラブルかつ低レイテンシなGCである。「Shenandoah」はGCによるアプリケーションの停止時間を最小限に抑えることをおもな目的として開発されたGCで、こちらはJava 12から搭載されている。

いずれも、これまではExperimantalだったため有効化するためにはコマンドラインオプションで「-XX:+UnlockExperimentalVMOptions」の指定が必要だった。Java 15では正式版となったのでこのオプションが不要になる。
言語仕様およびAPIに関する新機能

言語仕様およびAPIの新機能に関するJEPは次の8個になる。

JEP 339: Edwards-Curve Digital Signature Algorithm (EdDSA)
JEP 360: Sealed Classes (Preview)
JEP 371: Hidden Classes
JEP 373: Reimplement the Legacy DatagramSocket API
JEP 375: Pattern Matching for instanceof (Second Preview)
JEP 378: Text Blocks
JEP 383: Foreign-Memory Access API (Second Incubator)
JEP 384: Records (Second Preview)

このうち、JEP 378の「Text Blocks」は第9回の記事で紹介したが、Java 13および14にプレビュー版として搭載されていたものが、今回正式版に昇格された。JEP 339は暗号化署名のAPIにおいてRFC 8032で規定されているEdDSA(エドワーズ曲線デジタル署名アルゴリズム)のサポートを追加するというもの。

JEP 371の「Hidden Classes」は、他のクラスのバイトコードから直接利用できない"隠しクラス"を定義可能にするというものになる。Javaでは、コンパイル時にclassファイルを生成するのではなく、実行時に動的にクラスを生成するという実装方式が使われることがある。ラムダ式などはその代表例と言える。現状では、そのような動的に生成されたクラスでも、リフレクション経由で外部からアクセスできてしまう。Hidden Classは、動的に生成されるクラスを外部から隠蔽してアクセスできないようにするものになる。

JEP 373は、UDPを扱うDatagramSocket APIを、よりシンプルで近代的な実装に作り直したというもので、メンテナンスやデバッグが容易になるという利点がある。また、現在OpenJDKではJavaへの軽量スレッドを導入する「Project Loom」というプロジェクトが進行中だが、JEP 373によってProject Loomで追加される仮想スレッドにも対応しやすくなるという。

JEP 383はヒープ外のメモリを扱う方法を提供するAPIで、Java 14でIncubatorとして試験的に導入されたものが、Java 15ではSecond Incubatorとなった。ヒープ外のメモリにアクセスするには、これまではByteBufferを使う方法、JNI(Java Native Interface)を使う方法、非推奨であるsun.misc.Unsafeクラスを使う方法などがあったが、いずれも大きな問題を抱えていた。JEP 383はその問題を解消し、安全にヒープ外のメモリを扱えるようにする目的で導入された。

JEP 360、JEP 375、JEP 384については後述する。
「削除された」または「非推奨になった」機能

以下の4つのJEPは、Java 15で廃止される、または非推奨になる機能に関するものである。

JEP 372: Remove the Nashorn JavaScript Engine
JEP 374: Disable and Deprecate Biased Locking
JEP 381: Remove the Solaris and SPARC Ports
JEP 385: Deprecate RMI Activation for Removal

JEP 372のNashornの削除については第14回、第15回、第16回の記事で詳しく解説した。JEP 374では、HotSpot VMの最適化手法であるBiased Lockingを非推奨にされた。Biased Lockingは古いアプリケーションではパフォーマンスを向上させるのに有効だったが、最近のプロセッサではあまり効果が期待できず、場合によってはパフォーマンスが悪化することもある。Biased Lockingを維持するコストに対してメリットが薄いため、Java 15で非推奨にされ、有効にするには -XX:+UseBiasedLocking オプションの指定が必要になった。

JEP 381は、OpenJDKがSolaris/SPARCのサポートを停止するというもので、リポジトリからソースコードが削除された。JEP 385では、リモートメソッド呼び出しをサポートするRMI Activationが、将来的な削除に向けて非推奨にされた。