Java10のJEP以外の変更まとめ

いよいよ今日、Java 10がリリースされますね。
~~たぶん~~ここからダウンロードできるように~~なると思います~~ なりました。
http://jdk.java.net/10/

Java 10の新機能について、JEPがあるものについてはこちらにまとめました。
[Java 10新機能まとめ - Qiita](https://qiita.com/nowokay/items/d9bc4b3f715d17c2830d)

ただ、JEPがあるもの以外にも結構変更はあります。
ここではJEP以外の変更について、影響がありそうなものをAPIとその他についてまとめてみます。
ここからの抽出です。詳しく知りたい人はこちらを。
[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)

# APIの変更

## プロセスIDの取得
`java.lang.management.RuntimeMXBean`に`getPid()`メソッドが追加されて、プロセスIDが取れるようになりました。

```java
import java.lang.management.ManagementFactory;

long pid = ManagementFactory.getRuntimeMXBean().getPid();
System.out.println(pid);
```

ちなみに、読みやすさを考えると、このような場合は`var`は使わないほうがいいですね。
「`getPid()`の定義をみれば`long`であることはわかるから`var`でいい」とは言いがたい。

## バージョン取得

Java 9で`Runtime.version()`が追加されましたが、それで取れる`Runtime.Version`クラスが新しいバージョニングに従って変更されています。
`feature()`、`interim()`、`update()`、`patch()`が追加され、`major()`、`minor()`、`security()`がDeprecatedになりました。

```java
Runtime.Version version = Runtime.version();
System.out.printf("%d.%d.%d.%d%n",
        version.feature(), version.interim(), version.update(), version.patch());
```

## ReaderからWriterへの転送
Java 9で`java.io.InputStream`に`transferTo`メソッドが追加されて`InputStream`から`OutputStream`への転送ができるようになっていましたが、Java 10では`java.io.Reader`に`transferTo`メソッドが追加されて、`Reader`でも`Writer`への転送ができるようになりました。

```java
var sr = new StringReader("abc\ndef\n");
var sw = new StringWriter();
sr.transferTo(sw);
System.out.println(sw);
```

こういった`new`を使う場合は、右辺をみれば型がわかるので、`var`でいいと思います。

## List/Set/Mapの変更不能なコピー作成
`java.util.List`、`java.util.Set`、`java.util.Map`に`copyOf`メソッドが追加されて、`List`などのコピーが作れるようになりました。

```java
var list = List.copyOf(List.of("aa", "bb", "cc"));
```

`List`の場合は、`java.util.ImmutableCollections$ListN`という、`List.of`でも使われている非公開クラスのインスタンスになっています。要素が0～2個の場合にはList0など専用クラスのインスタンスになります。
この例のように、もともと`ImmutableCollections$ListN`だった場合には、与えたインスタンスがそのまま返されます。
JDK11ではListNに統一されそう。
http://hg.openjdk.java.net/jdk/jdk/rev/a14ede52a278

ところで`copyOf`は`var`で受けていいかどうか微妙ですね。

## Optinal/OptionalIntその他のorElseThrow()
`Optional`その他にはすでに`orElseThrow(Supplier<Throwable>)`が用意されています。
Java 10では引数なしの`orElseThrow()`が追加されました。
`get()`メソッドは`Optional`が値を持たないときには例外を投げます。そのため、この記事を書いた当初は`orElseThrow()`って必要ないのではと思って省略していたのですが、実際には`get()`は例外が投げられることをちゃんと意識して使う必要があり、そうであれば`get()`ではなく`orElseThrow()`を常用したほうがいいのではと思い至りました。
もしかしたら、将来的には`get()`はDeprecatedになる可能性もあるという雰囲気らしい。

## Streamからの変更不能なList/Set/Map生成

`java.util.stream.Collectors`に`toUnmodifiableList`、`toUnmodifiableSet`、`toUnmodifiableMap`が追加されました。

```java
List<String> strs = Stream.of("aa", "bb")
        .collect(Collectors.toUnmodifiableList());
```

`toUnmodifiableSet()`は重複があっても問題なく、どれかひとつが選ばれますが、`toUnmodifiableMap()`はキーに重複があると`java.lang.IllegalStateException`が投げられます。

## javax.ButtonModel#getGroup()

Swingにも変更が！！！

# その他の変更

## {@ Summary} JavaDocタグ

JavaDocのサマリーが、`{@Summary}`タグを使うと複数行で書けるようになりました。

## Docker対応

いままで、DockerでJVMを動かしていてもCPU数やメモリなどはDockerの設定を無視してプラットフォームのCPU数やメモリサイズを返していましたが、Java 10からはDockerの設定を読むようになりました。
これはJavaをメインで使ってなくてもHadoopやSparkなどをDockerで使うときに影響があったので、ありがたい人も多いかも。

## -d32 -d64の削除

JVMが32bit版か64bit版かを選ぶスイッチがありましたが、64bit版しか提供されなくなったのでこれらのスイッチはなくなりました。

## policytoolの削除

削除されました

## Kerberosの設定

`INCLUDEDIR`に`*.conf`というファイルがあると、`krb5.conf`に取り込まれます。

## まちがってDeprecatedになったものが復活

`XMLInputFactory#newFactory()`に間違って`@Deprecated`がつけられていましたが、外されました。
こんなこともあるんですね。