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
おそらく、コードを書く上では最大そして唯一の変更であるローカル変数型推論です。
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
ということで、ここからはコードを書くときにはあまり関係ないので、さっと流します。
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
JVMからGCを独立させるために、GCインタフェースを導入しています。
これによって、GCのモジュラリティが高まるので、GCを追加したり削除したりしやすくなります。
Java11ではEpsillonGCという素敵なGC(まったくメモリを解放しないGC)も入るし、ZGCがオープンソースになったり、Shenandoahなどもあったりと、これから先のGCの動きがやりやすくなるんだと思います。
307: Parallel Full GC for G1
G1GCでの最悪ケースのレイテンシを、Full GCを並列化することで改善しようというものです。
Java 9からG1GCがデフォルトになりましたが、Java 8までのデフォルトGCであるパラレルGCでは並列にFull GCが行われていたため、移行を よりスムーズにできるようにということのようです。
310: Application Class-Data Sharing
JDK5で導入されていたクラスデータシェアリング(CDS)をアプリケーションクラスにも使えるようにすることで、Javaプロセス間でクラスのメタデータを共有したり、起動時間や利用メモリなどを改善します。
312: Thread-Local Handshakes
VM全体のsafepointに影響せずに個別のスレッドのコールバックを実行できるようにする。それによってスタックトレースの取得やGCが改善する、らしい。
313: Remove the Native-Header Generation Tool (javah)
JNI用のCヘッダーの生成はJava8からjavacでできるようになったのでjavahは削除されます。
314: Additional Unicode Language-Tag Extensions
java.util.Localeその他APIでのBCP47言語タグへの対応を拡張。Java7でカレンダーca
と数値nu
に対応していたものを、通貨cu
、週の起日fw
、地域rg
、タイムゾーンtz
も対応するように拡張されます。
316: Heap Allocation on Alternative Memory Devices
NV-DIMMなど、ユーザーが指定した他のメモリデバイスにもJavaオブジェクトのヒープを配置できるようにする。
将来的なシステムでは3D XPointのようなメモリを使って複合的なメモリアーキテクチャが搭載されて、DRAMに加えて、異なる特性を持ったnon-DRAMも使うことになる。
応用例としては、優先度の高いプロセスがDRAMを使って、優先度の低いプロセスはNV-DIMMを使うとか、ビッグデータやインメモリDBでNV-DIMMを使うとかが考えられています。
317: Experimental Java-Based JIT Compiler
試験的に、JavaベースのJITコンパイラであるGraalをLinux/x64プラットフォームで有効にします。
GraalはJDK9で導入された事前コンパイル(AoT)の基礎になっていますが、JITコンパイラとしても利用して、JavaベースJITの次の段階への調査を行います。
319: Root Certificates
いままではOpenJDKにはデフォルトではルート証明書がなくTLSなどセキュリティが大事な機能が動かなかったので、OpenJDKで開発しやすくしてOracle JDKとの差をうめるためにルート証明書を用意するということらしい。
322: Time-Based Release Versioning
時間ベースのリリースに対応して、バージョン記述が決めなおされます。
次のような形式になります。
$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.Version
のfeature()
、interim()
、patch()
、update()
で取得できます。