Edited at

Java 10新機能まとめ

More than 1 year has passed since last update.

Java 10が出ますね。Java 9なんてなかった!

しかしながら、どんな機能があるかよくわからないので、まとめてみます。

ここに並んでいるJEPを簡単に紹介する感じで。

http://openjdk.java.net/projects/jdk/10/

APIの追加など、JEP以外の変更はこちらにまとめました。

Java10のJEP以外の変更まとめ - Qiita

すべての変更点はこちらにまとまってます。

109 New Features In JDK 10 - Azul Systems, Inc.

OpenJDKのダウンロードはこちら

JDK 10 GA Release

Oracle JDKのダウンロードはこちら

Java SE Development Kit 10- - Downloads


286: Local-Variable Type Inference

http://openjdk.java.net/jeps/286

おそらく、コードを書く上では最大そして唯一の変更であるローカル変数型推論です。

var str = "123";

var list = List.of("123");

のように書けるようになります。

通常コードを書くときに使うと変数の型がわからなくなることが多く、いままでわかっていた型がわからなくなるということは嫌われがちなので、案外使えるシチュエーションは少ない気もします。

とりあえず使えそうなのは、次のように型がある程度明示的な場合でしょうか。

var strs = new ArrayList<String>(); // newする

var props = (Map<String, List<String>>)input.getAsObject("props"); // キャスト
var map = Map.of("apple", "りんご",
"grape", "ぶどう"); // ファクトリやビルダー

まとめると、右辺に型が書いてあれば左辺には不要でvarでいい、それ以外はvarは使わない、という感じですね。

けど、JShellでは無条件に便利です。

varが使えそうで使えないところとして、ラムダ引数があります。

Stream.of("abc").forEach(s -> System.out.println(s));

Stream.of("abc").forEach((String s) -> System.out.println(s));

を型推論させたものですが、これを

Stream.of("abc").forEach((var s) -> System.out.println(s));

と書くことはできません。まあローカル変数型推論であって、ラムダ引数はローカル変数ではないので、使えないということですね。

ただまあ、使えそうに見えるので、Java 11からはラムダ引数でもvarが使えるようになります。

また、varを導入するにあたって、言語仕様はちょこちょこ変わっています。

大きいものとして、varは予約語としてではなく、予約型として導入されています。なので、変数名やメソッド名、パッケージ名にvarは使えますが、クラス名などにはvarが使えなくなりました。

言語仕様では、型に関してはIdentifierではなくTypeIdentifierというのが導入されて、型が書ける部分がIdentifierからTypeIdentifierに変更されています。

あと、こんなことができます。

var anon = new Object() {

private int a() {
return 3;
}
};
System.out.println(anon.a());

ちなみに

var s = List.of("a", 1);

を含むコードを-gオプション付きでコンパイルするとbuild 46ではjavacが落ちます。

これらは大丈夫です。

var t = List.of("a");

var u = List.of("a", 1, Optional.empty());
var v = List.of("a", 1, List.of());

すでにbitterfoxさんがパッチを送ってくださっています。


296: Consolidate the JDK Forest into a Single Repository

http://openjdk.java.net/jeps/296

ということで、ここからはコードを書くときにはあまり関係ないので、さっと流します。

JEP 296は、OpenJDK上のリポジトリを統合するものです。最近のシングルリポジトリの流れに従ったものですね。

いままでOpenJDKのソースの取得はスクリプトでいろんなリポジトリから拾い集める感じだったのですが、Mercurialのコマンド一発でソースが取得できるようになりました。開発も楽になってると思います。

JDK9のリポジトリを見るとわかるのですけど、それぞれ7つのリポジトリを内包しています。

http://hg.openjdk.java.net/jdk9

JDK10では古いリポジトリが残っていますが、masterに統合されています。

http://hg.openjdk.java.net/jdk10

そして、リポジトリが統合されたことで、いままではバージョンごとに別プロジェクトだったのが、jdkプロジェクトの下に各バージョンリポジトリを作る感じになっています。

http://hg.openjdk.java.net/jdk


304: Garbage-Collector Interface

http://openjdk.java.net/jeps/304

JVMからGCを独立させるために、GCインタフェースを導入しています。

これによって、GCのモジュラリティが高まるので、GCを追加したり削除したりしやすくなります。

Java11ではEpsillonGCという素敵なGC(まったくメモリを解放しないGC)も入るし、ZGCがオープンソースになったり、Shenandoahなどもあったりと、これから先のGCの動きがやりやすくなるんだと思います。


307: Parallel Full GC for G1

http://openjdk.java.net/jeps/307

G1GCでの最悪ケースのレイテンシを、Full GCを並列化することで改善しようというものです。

Java 9からG1GCがデフォルトになりましたが、Java 8までのデフォルトGCであるパラレルGCでは並列にFull GCが行われていたため、移行を よりスムーズにできるようにということのようです。


310: Application Class-Data Sharing

http://openjdk.java.net/jeps/310

JDK5で導入されていたクラスデータシェアリング(CDS)をアプリケーションクラスにも使えるようにすることで、Javaプロセス間でクラスのメタデータを共有したり、起動時間や利用メモリなどを改善します。


312: Thread-Local Handshakes

http://openjdk.java.net/jeps/312

VM全体のsafepointに影響せずに個別のスレッドのコールバックを実行できるようにする。それによってスタックトレースの取得やGCが改善する、らしい。


313: Remove the Native-Header Generation Tool (javah)

http://openjdk.java.net/jeps/313

JNI用のCヘッダーの生成はJava8からjavacでできるようになったのでjavahは削除されます。


314: Additional Unicode Language-Tag Extensions

http://openjdk.java.net/jeps/314

java.util.Localeその他APIでのBCP47言語タグへの対応を拡張。Java7でカレンダーcaと数値nuに対応していたものを、通貨cu、週の起日fw、地域rg、タイムゾーンtzも対応するように拡張されます。


316: Heap Allocation on Alternative Memory Devices

http://openjdk.java.net/jeps/316

NV-DIMMなど、ユーザーが指定した他のメモリデバイスにもJavaオブジェクトのヒープを配置できるようにする。

将来的なシステムでは3D XPointのようなメモリを使って複合的なメモリアーキテクチャが搭載されて、DRAMに加えて、異なる特性を持ったnon-DRAMも使うことになる。

応用例としては、優先度の高いプロセスがDRAMを使って、優先度の低いプロセスはNV-DIMMを使うとか、ビッグデータやインメモリDBでNV-DIMMを使うとかが考えられています。


317: Experimental Java-Based JIT Compiler

http://openjdk.java.net/jeps/317

試験的に、JavaベースのJITコンパイラであるGraalをLinux/x64プラットフォームで有効にします。

GraalはJDK9で導入された事前コンパイル(AoT)の基礎になっていますが、JITコンパイラとしても利用して、JavaベースJITの次の段階への調査を行います。


319: Root Certificates

http://openjdk.java.net/jeps/319

いままではOpenJDKにはデフォルトではルート証明書がなくTLSなどセキュリティが大事な機能が動かなかったので、OpenJDKで開発しやすくしてOracle JDKとの差をうめるためにルート証明書を用意するということらしい。


322: Time-Based Release Versioning

http://openjdk.java.net/jeps/322

時間ベースのリリースに対応して、バージョン記述が決めなおされます。

次のような形式になります。

$FEATURE.$INTERIM.$UPDATE.$PATCH

半年に一回のリリースで$FEATUREはひとつ増え$UPDATEは0になります。$INTERIMは常に0。フィーチャーリリースの1か月後と4か月後のメンテナンスリリースで$UPDATEがひとつ増えます。$PATCHは通常は使いません。

次の3月に出るリリースは10。4月に出るのが10.0.1。7月に出るのが10.0.2、9月に出るのが11。

これらのバージョン番号はjava.lang.Runtime.Versionfeature()interim()patch()update()で取得できます。