ここでは、Java 9 以降 Java 13 までに追加された機能をいくつか抜粋して紹介したいと思います。
Java 14 についてはこちらの記事をご覧ください。
Java 9
JEP 102: Process API Updates
Process API が拡張され、java.lang.Process から取得できる情報が増えたり、新クラス java.lang.ProcessHandle を使用してより詳細に外部プロセスを監視・制御できるようになりました。
JEP 200: The Modular JDK
JEP 201: Modular Source Code
JEP 220: Modular Run-Time Images
JEP 260: Encapsulate Most Internal APIs
JEP 261: Module System
JEP 282: jlink: The Java Linker
いわゆる Project Jigsaw です。語り始めると長くなりそうなので、また別の機会に……。
JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)
Java のインタラクティブシェルが追加されました。
JEP 259: Stack-Walking API
スタックフレームの情報にきれいにアクセスできる API が追加されました。
JEP 269: Convenience Factory Methods for Collections
各種 Collection のファクトリメソッドが追加されています。List::of, Set::of, Map::of など。
JEP 280: Indify String Concatenation
Indify とは、Invoke Dynamic 化という意味です。
String の結合 (+ 演算子) は、これまで StringBuilder を使うようにコンパイルされていましたが、Java 9 からはまったく違う方法になりました。
結合後の合計のバイト長ちょうどのバイト配列を先に用意して、各 String の内部バッファを適切な位置にコピーします。こうすることで、初回の Invoke Dynamic のブートストラップ処理を除けば高速化します。
Java 10
JEP 286: Local-Variable Type Inference
初期化付きで変数を宣言するときに、変数の型を明示せず、var という仮想型名を書くと、初期化子の型から推論して変数の型を決めてくれる、という記法が導入されました。
変数の型はコンパイル時に決まります。何でも入れていい変数になるわけではありません。
Java 11
JEP 318: Epsilon: A No-Op Garbage Collector (Experimental)
Epsilon GC は、ガーベジをコレクションしないガーベジコレクタです。メモリの割り当てはしますが、解放はしません。ヒープが無くなったら終了です。
一見意味が無いように思えますが、以下のような用途があります。
- パフォーマンス計測、メモリ使用量確認といった、GC の影響の無い状態で挙動を観測したい場合
- VM を開発するとき
- ヒープが足りることが分かっている短いプログラムを動かすとき
- 限界までレイテンシやスループットを改善したいとき
JEP 321: HTTP Client (Standard)
HTTP クライアントが標準 API に入りました。HTTP/2 にも対応しています。
JEP 323: Local-Variable Syntax for Lambda Parameters
Lambda 式のパラメータに var キーワードを付けることができるようになりました。
元々型推論されるので、直接的な意味は無いのですが、こうすることで @NotNull などのアノテーションを付与できるようになりました。
JEP 328: Flight Recorder
JDK Flight Recorder が導入されました。
JEP 330: Launch Single-File Source-Code Programs
単一のソースファイルで出来ているプログラムについて、ソースファイルを直接 java コマンドに渡すと、実行してくれるようになりました。これまでは javac Main.java; java Main といった要領でしたが、なんと java Main.java でいきなり実行してくれます。class ファイルも生成されません。
さらに、--source <version> 引数でソースバージョンを指定できるのですが、--source が指定されているときは、拡張子が java でなくても構わなくなります。
これが何を意味するかというと、UNIX 系 OS でスクリプトのように使えるということになります。
#!/usr/bin/env java --source 14 public class SingleFile { public static void main(final String[] args) { System.out.println("Hello, World!"); } }
こういう内容で SingleFile というファイルを作っておき、chmod +x して path を通しておけば、SingleFile というコマンドとして使うことができます。
気軽に Java プログラムを書いてビルド無しで実行できるというのは、案外便利かもしれません。