Java 10新機能まとめ

Java 10が出ますね。Java 9なんてなかった！
しかしながら、どんな機能があるかよくわからないので、まとめてみます。
ここに並んでいるJEPを簡単に紹介する感じで。
http://openjdk.java.net/projects/jdk/10/

APIの追加など、JEP以外の変更はこちらにまとめました。
[Java10のJEP以外の変更まとめ - Qiita](https://qiita.com/nowokay/items/4fa289f825820229c5cb)

すべての変更点はこちらにまとまってます。
[109 New Features In JDK 10 - Azul Systems, Inc.](https://www.azul.com/109-new-features-in-jdk-10/)

OpenJDKのダウンロードはこちら
[JDK 10 GA Release](http://jdk.java.net/10/)

Oracle JDKのダウンロードはこちら
[Java SE Development Kit 10- - Downloads](http://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html)

# 286: Local-Variable Type Inference
http://openjdk.java.net/jeps/286

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

```java
var str = "123";
var list = List.of("123");
```

のように書けるようになります。
通常コードを書くときに使うと変数の型がわからなくなることが多く、いままでわかっていた型がわからなくなるということは嫌われがちなので、案外使えるシチュエーションは少ない気もします。
とりあえず使えそうなのは、次のように型がある程度明示的な場合でしょうか。

``` java
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が使えそうで使えないところとして、ラムダ引数があります。

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

は

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

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

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

と書くことはできません。まあローカル変数型推論であって、ラムダ引数はローカル変数ではないので、使えないということですね。
ただまあ、使えそうに見えるので、Java 11からはラムダ引数でも`var`が使えるようになります。

また、varを導入するにあたって、言語仕様はちょこちょこ変わっています。
大きいものとして、varは予約語としてではなく、予約型として導入されています。なので、変数名やメソッド名、パッケージ名にvarは使えますが、クラス名などにはvarが使えなくなりました。
言語仕様では、型に関してはIdentifierではなくTypeIdentifierというのが導入されて、型が書ける部分がIdentifierからTypeIdentifierに変更されています。

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

```java
var anon = new Object() {
    private int a() {
        return 3;
    }
};
System.out.println(anon.a());
```

ちなみに

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

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

これらは大丈夫です。

``` java
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.Version`の`feature()`、`interim()`、`patch()`、`update()`で取得できます。