Java8からJava11への変更点

# Java 8からJava 11
http://openjdk.java.net/projects/jdk9/
http://cr.openjdk.java.net/~iris/se/9/latestSpec/apidiffs/overview-summary.html

https://openjdk.java.net/projects/jdk/10/
http://cr.openjdk.java.net/~iris/se/10/latestSpec/apidiffs/overview-summary.html

https://openjdk.java.net/projects/jdk/11/
http://cr.openjdk.java.net/~iris/se/11/latestSpec/apidiffs/overview-summary.html

# 言語

まず言語についての変更点です。

## var
http://openjdk.java.net/jeps/286
ローカル変数について型推論ができるようになりました。

```java
var a = "Foo";
```

指針については次のような感じがいいかなと。

- `new`、`List.of`など右辺に型があるものは`var`を使う方がいい(`Integer`、`Long`など以外)
- `java.lang`、`java.util`などの基本的なクラスには`var`を使っていい
- `Integer`や`Long`などラッパークラスは扱い注意なので`var`を使わないほうがいい
- 基本型には`var`を使ってもいい
- アプリケーションクラスには`var`を使わないほうがいい

ラッパークラスの変数を使う場合はnullを扱うということなので、型を明示しておいたほうがいいと思います。nullを使わないなら基本型を。
項目1に当てはめると次のような書き方はOKになります。

```java
var count = Long.valueOf("123");
```

けれども、`Integer`や`Long`のメソッドに関しては基本型を返すものとラッパー型を返すものが混在しているので、型を明示しておいたほうが安全です。
`var`で受け取る場合は基本型になっている、というふうにしておいたほうがいいと思います。

## private interface methods
http://openjdk.java.net/jeps/213

interfaceにprivateメソッドが使えるようになりました。

Java8 でstaticメソッドやdefaultメソッドが使えるようになっているので、その共通処理を`private`で書くことができます。

## effective final in try-with-resource
http://openjdk.java.net/jeps/213

実質的にfinalな変数について、try-with-resourceで変数だけを指定することができるようになりました。
いままでは`try`の外で定義された`Closable`な変数についてtry-with-resourceで自動closeしたいときは、別の変数に割り当てるということが必要でした。例えばfinallyで使いたいという場合にtryの外での変数定義が必要でしたが、そういう場合に使えます。

```java
var io = new InputStream();
try (var io2 = io) {
  ...
}
```
↓

```java
var io = new InputStream();
try (io) {
  ...
}
```

## <> in anonymous
匿名クラスにダイヤモンド演算子での型推論ができるようになりました。

```java
List<String> strs = new ArrayList<>() {{
  this.add("aa");
  this.add("bb");
}};
```

## _が利用不可

変数として`_`が使えないようになりました。

# API

ここからは標準ライブラリの変更点についてクラスごとにまとめます。

Java 11のAPIについてはこちらもどぞ
https://nowokay.hatenablog.com/entry/20180704/1530712754

## java.lang

### String
#### Compact String
http://openjdk.java.net/jeps/254
Java9で入っています。
Java8までは文字をcharとしてUTF-16で保持していたので1文字につき2バイトを使っていましたが、アルファベットや数字などASCIIキャラクタだけの文字列は1バイトで保持するようになりました。

#### Indy String concatenation
http://openjdk.java.net/jeps/280

いままで、`+`での文字列の連結は`StringBuilder`に展開されましたが、InvokeDynamicで実行時に確定するようになります。

```java
"aa"+ a
```
↓

```java
new StringBuilder("aa").append(a);
```
↓
Dynamic Invoke


#### repeat(n)
繰り返せる

```
jshell> "test".repeat(3)
$1 ==> "testtesttest"
```

#### isBlank()

isBlankはUTFのスペース文字


#### strip() / stripLeading() / stripTrailing()

trim() / trimLeft() / trimRight()のUTF対応版

#### lines()

改行ごとの文字列のStreamを返す

```java
"test\nprogram\n".lines()
  .map(String::strip)
  .collect(Collectors.joining("\n"))
```

のようにすると各行の前後のスペースが取り除けるわけです。

## java.util

### List/Set/Map
#### of
http://openjdk.java.net/jeps/269

Immutableなコレクションを返します

```java
var strs = List.of("apple", "banana");
var sets = Set.of("apple", "banana");
var dict = Map.of(
  "apple", "りんご",
  "banana", "バナナ");
```

#### copyOf
Immutableなコピーを返す

### Map
#### ofEntries() / entry()

Mapには`of`だけでなく`ofEntries()`も追加されています。

```java
import static java.util.Map.entry;

var map = Map.ofEntries(
  entry("key1", "value1"),
  entry("key2", "value2"));
```

### Predicate
not

メソッドリファレンスの反転が便利に

```java
lines.stream()
  .filter(not(String::isEmpty))
  .forEach(System.out::println);
```

### Collection
#### toArray(IntFunction)

Listなどを配列に変換するとき、サイズをあわせた配列をあらかじめ用意する必要がありましたが、`strs.toArray(String[]::new)`のようにして配列を生成できます

### Stream
#### dropWhile / takeWhile

Java 8では「データにstartがきてからendがくるまで」というようなStream処理はできませんでしたが、Java 9で導入されたdropWhile / takeWhileを使うと実装できるようになります。

```java
jshell> Stream.of("one", "start", "two", "three", "end", "four").
   ...> dropWhile(s -> !s.equals("start")).
   ...> takeWhile(s -> !s.equals("end")).
   ...> forEach(System.out::println)
start
two
three
```

この場合`start`まで入っているので、skipする必要がありますね。

```java
jshell> Stream.of("one", "start", "two", "three", "end", "four").
   ...> dropWhile(s -> !s.equals("start")).
   ...> skip(1).
   ...> takeWhile(s -> !s.equals("end")).
   ...> forEach(System.out::println)
two
three
```

#### ofNullable

#### iterate

引数2つのiterateはJava8からありましたが、必ずlimitなどで停止条件をつける必要がありました。

```java
IntStream.iterate(0, i -> i + 3).limit(5)
  .forEach(System.out::println);
```

`takeWhile`もなかったので、結構使いどころが難しかったです。
そして、`takeWhile`を組み合わせて`iterate`を使えるようになりました。
ということで、for文のように使えます。

```java
IntStream.iterate(0, i -> i < 10, i -> i + 3)
  .forEach(System.out::println);
```

これ、次のような書き方をすると帰ってこなくなります。なぜかは考えてみてください。

```java
IntStream.iterate(0, i -> i < 10, i -> i++)
  .forEach(System.out::println);
```

これならいける

```java
IntStream.iterate(0, i -> i < 10, i -> ++i)
  .forEach(System.out::println);
```

### Optional/OptionalInt/OptionalLong/OptionalDouble
#### orElseThrow()
#### isEmpty()
#### stream()

OptionalからStreamへの変換が簡単になりました。
このことで、Stream中でOptionalが帰ってくるときに`filter(Optional::isPresent)`をはさむ必要がなくなっています。
たとえば`getById`がOptionalを返すとして

```java
ids.map(Data::getById)
   .filter(Optional::isPresent)
   .collect(Collectors.toList())
```

のようにしていたものを

```java
ids.flatMap(id -> getById(id).stream())
   .collect(Collectors.toList())
```

のような感じでflatMapで書けるようになります。

#### ifPresentOrElse
#### or

OptionalがEmptyなら次のOptionalのようなことが書きやすくなりました。

### Collectors
#### toUnmodifiableList / toUnmodifiableSet / toUnmodifiableMap

イミュータブルなコレクションに値を格納するCollectorです

#### filtering
#### flatMapping

### Enumeration
asIterator

### Objects
#### requireNonNullElse
#### requireNonNullElseGet

## java.io

### Path
of

### Files
#### writeString

テキストをファイルに書き込む処理が一行に。

#### readString

テキストをファイルから読み込む処理が一行に。

### Reader
#### transferTo

Readerで読み取った内容をそのままWriterに書くということが一行に

#### nullReader
### Writer
#### nullWriter

### InputStream
#### transferTo

InputStreamで読み取った内容をそのままOutputStreamに書くということが一行に

#### nullInputStream

### OutputStream
#### nullOutputStream

## java.net.http

HTTPアクセスが刷新されました。

## sun.misc
いろいろ削除されたっぽい

### sun.misc.BASE64Encoder / BASE64Decoder
Java9で削除されているので代わりにjava.util.BASE64.Encoder / Decoderを使う

# JVM

## Log
http://openjdk.java.net/jeps/158
http://openjdk.java.net/jeps/271

## G1GC is the default GC
http://openjdk.java.net/jeps/248 

## ZGC

## CMS is deprecated
http://openjdk.java.net/jeps/291

## Ahead of time compilation
http://openjdk.java.net/jeps/295

# 機能

## JShell
http://openjdk.java.net/jeps/222

## Launch Single-File Source-Code Programs

ソース1つのJavaコードをjavacでコンパイルすることなくjavaコマンドで実行できるようになりました。

## Module System

## Java EE and CORBA is dropped