Java 11 で追加されたAPIの一覧とサンプルコード

2018年9月25日に、ついに Java 11 がリリースされました :laughing:

そこで、今回は Java 11 で新しく追加された API [^pre] について、一挙にまとめてみました！

- この記事の対象は、 `java.*` パッケージです。
    - `javax.*`, `sun.*`, `jdk.*` にも追加・変更がありましたが、今回は対象外です。
- おかしなところがあれば、編集リクエストかコメントをお願いします！

[^pre]: `@since 11` が付与されているもの

# java.lang
## String class

- `public String strip()`
 - 先頭と末尾の空白を除去します。
- `public String stripLeading()`
 - 先頭の空白を除去します。
- `public String stripTrailing()`
 - 末尾の空白を除去します。

既にある `trim()` と似ていますが、若干挙動が違います。

- `trim()` は、半角スペースやタブ(`\t`)、改行 (`\r`, `\n`) といった、`'\u0020'` よりも小さなコードポイントの文字を除去
- `strip()` は、Unicode Block の White Space を除去

なので、`trim()` では No Break Space (`\u00A0`) や全角スペース (`\u3000`) は除去されませんが、`strip()` では除去されます。

```java

jshell> " ABC ".trim()    // 半角スペース
$1 ==> "ABC"

jshell> "ABC\r\n".trim()    // 改行
$2 ==> "ABC"

jshell> "ABC　".trim()    // 全角スペース
$3 ==> "ABC　"

jshell> " ABC ".strip()    // 半角スペース
$4 ==> "ABC"

jshell> "ABC\r\n".strip()    // 改行
$5 ==> "ABC"

jshell> "ABC　".strip()    // 全角スペース
$6 ==> "ABC"

jshell> " ABC ".stripLeading()
$7 ==> "ABC "

jshell> " ABC ".stripTrailing()
$8 ==> " ABC"
```

- `public boolean isBlank()`
 - 空白だけを含む文字列の場合、true を返します。

こちらも `strip()` と同様に、Unicode Block の White Space を空白と判定します。

```java
jshell> " ".isBlank()    // 半角スペース
$1 ==> true

jshell> "\u3000".isBlank()    // 全角スペース
$2 ==> true

jshell> "\r\n".isBlank()    // 改行
$3 ==> true

jshell> "".isBlank()
$4 ==> true

jshell> " ABC ".isBlank()
$5 ==> false
```

- `public Stream<String> lines()`
 - `\r`, `\n`, `\r\n` で区切った文字列をストリーム `Stream<String>` で返します。

「テキストを一行ずつ分割して処理したい！」というときに、さくっと書けるようになりました。

```java
jshell> "A\r\nB".lines().toArray()
$1 ==> Object[2] { "A", "B" }

jshell> "A\rB".lines().toArray()
$2 ==> Object[2] { "A", "B" }

jshell> "A\nB".lines().toArray()
$3 ==> Object[2] { "A", "B" }

jshell> "A\nB\n\nC".lines().toArray()
$4 ==> Object[4] { "A", "B", "", "C" }
```

- `public String repeat(int count)`
  - 指定された回数だけ繰り返した文字列を返します。

地味に欲しかったやつです。

```java
jshell> "ABC".repeat(3)
$1 ==> "ABCABCABC"

jshell> "ABC".repeat(0)
$2 ==> ""

jshell> "ABC".repeat(-1)
|  例外java.lang.IllegalArgumentException: count is negative: -1
|        at String.repeat (String.java:3149)
|        at (#35:1)
```

## StringBuilder class

- `public int compareTo(StringBuilder another)`
 - ほかの StringBuilder と文字列を比較します。

`StringBuilder` に `Comparable<String>` インタフェースが実装されたことに伴い、このメソッドが追加されました。

```java
jshell> new StringBuilder("ABC").compareTo(new StringBuilder("ABC"))
$1 ==> 0

jshell> new StringBuilder("ABC").compareTo(new StringBuilder("XYZ"))
$2 ==> -23

jshell> new StringBuilder("XYZ").compareTo(new StringBuilder("ABC"))
$3 ==> 23
```

## StringBuffer class

- `public int compareTo(StringBuffer another)`
 - ほかの StringBuilder と文字列を比較します。

`StringBuilder` と同様です。

## CharSequence Interface

- `public static int compare(CharSequence cs1, CharSequence cs2)`
 - 2つの文字列を比較します。

引数が `CharSequence` インタフェースなので、`String`, `StringBuilder`, `StringBuffer` などを渡せます。

```java
jshell> CharSequence.compare("ABC", "ABC")
$1 ==> 0

jshell> CharSequence.compare("ABC", new StringBuilder("ABC"))
$2 ==> 0

jshell> CharSequence.compare("ABC", new StringBuffer("ABC"))
$3 ==> 0
```

## Character class
 
- `public static final UnicodeBlock SYRIAC_SUPPLEMENT`
- `public static final UnicodeBlock CYRILLIC_EXTENDED_C`
- `public static final UnicodeBlock OSAGE`
- `public static final UnicodeBlock NEWA`
- `public static final UnicodeBlock MONGOLIAN_SUPPLEMENT`
- `public static final UnicodeBlock MARCHEN`
- `public static final UnicodeBlock IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION`
- `public static final UnicodeBlock TANGUT`
- `public static final UnicodeBlock TANGUT_COMPONENTS`
- `public static final UnicodeBlock KANA_EXTENDED_A`
- `public static final UnicodeBlock GLAGOLITIC_SUPPLEMENT`
- `public static final UnicodeBlock ADLAM`
- `public static final UnicodeBlock MASARAM_GONDI`
- `public static final UnicodeBlock ZANABAZAR_SQUARE`
- `public static final UnicodeBlock NUSHU`
- `public static final UnicodeBlock SOYOMBO`
- `public static final UnicodeBlock BHAIKSUKI`
- `public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F`

Unicode 10 のコードブロックの定義が追加されました。
Enum の `UnicodeScript` にも同様に追加されています。

```java
jshell> Character.UnicodeBlock.of(0x1B100)
$1 ==> KANA_EXTENDED_A
```

- `public static String toString(int codePoint)`
    - 指定されたコードポイントを表す `String` オブジェクトを返します。

もともと `toString(char c)` がありましたが、これだとサロゲートペアが使えませんでした。それが解消されました。

```java
jshell> Character.toString(0x20158)
$1 ==> '𠅘'
```

## Class class

- `public Class<?> getNestHost()`
 - ネストクラスの親のクラスを返します。
 - ネストされていないクラス、配列型、プリミィテブ型のクラス、void は、自分自身を返します。
- `public boolean isNestmateOf(Class<?> c)`
 - 引数で指定されたクラスとネスト関係にあるならば true を返します。
- `public Class<?>[] getNestMembers()`
 - ネストされたメンバーを返します。

クラスファイル仕様が更新されて NestHost, NestMembers 属性が追加されました。その情報を処理するためのメソッドです。
クラスファイルが Version 55.0 以降 (Java 11) でビルドされていないと、これらのメソッドは使えません。

下記の例では、`Character` のネストクラスである `UnicodeBlock` をサンプルにしています。

```java
jshell> Character.UnicodeBlock.class.getNestHost()
$1 ==> class java.lang.Character

jshell> Character.class.getNestHost()
$2 ==> class java.lang.Character

jshell> new Character.UnicodeBlock[0].getClass().getNestHost()
$3 ==> class [Ljava.lang.Character$UnicodeBlock;
```

```java
jshell> Character.UnicodeBlock.class.isNestmateOf(Character.class)
$1 ==> true

jshell> Character.class.isNestmateOf(Character.UnicodeBlock.class)
$2 ==> true

jshell> String.class.isNestmateOf(StringBuilder.class)
$3 ==> false
```

```java
jshell> Character.class.getNestMembers()
$1 ==> Class[5] { class java.lang.Character, class java.lang.Character$CharacterCache, class java.lang.Character$UnicodeScript, class java.lang.Character$UnicodeBlock, class java.lang.Character$Subset }
```

# java.lang.invoke

## ConstantBootstraps class

Java 11 で追加された Constant Dynamic (condy) を扱うためのクラスです。

詳しくは、じゅくちょーさんのブログに丸投げしますｗ
[Java 11 / JEP 309のConstant Dynamic（condy）を試す - Fight the Future](https://www.sakatakoichi.com/entry/java11condy)

# java.lang.ref

## Reference class

- `protected Object clone() throws CloneNotSupportedException`
 - `CloneNotSupportedException` をスローします。

これまで `clone()` できてしまっていたのが、できなくなりました。
ただ、protected なメソッドで、かつ Reference をわざわざ継承するようなこともないと思うので影響はないと思います。

```java
jshell> import java.lang.ref.*

jshell> new WeakReference<Object>(new Object()){
   ...>   public Reference test() throws CloneNotSupportedException{
   ...>     return (Reference)super.clone();
   ...>   }
   ...> }
$1 ==> $1@69a3d1d

jshell> $1.test();
|  例外java.lang.CloneNotSupportedException
|        at Reference.clone (Reference.java:389)
|        at $1.test (#32:1)
|        at (#35:1)
```

# java.io

## FileReader class

- `public FileReader(String fileName, Charset charset) throws IOException`
- `public FileReader(File file, Charset charset) throws IOException`
    - 指定されたファイルを、指定された文字コードで読み込む `FileReader` を作成します。 

これまで、文字コード指定したければ `FileInputStream` と `InputStreamReader` を組み合わせる必要がありましたが、その手間が解消されました。

```java
jshell> new FileReader("C:\\Users\\Yuzi\\Desktop\\Main.txt", java.nio.charset.StandardCharsets.UTF_8)
$1 ==> java.io.FileReader@6ebc05a6
```

## FileWriter class

- `public FileWriter(String fileName, Charset charset) throws IOException`
- `public FileWriter(String fileName, Charset charset, boolean append) throws IOException`
- `public FileWriter(File file, Charset charset) throws IOException`
- `public FileWriter(File file, Charset charset, boolean append) throws IOException`
 - 指定されたファイルに、指定された文字コードで書き込む `FileWriter` を作成します。 


これまで、文字コード指定したければ `FileOutputStream` と `OutputStreamWriter` を組み合わせる必要がありましたが、その手間が解消されました。

```java
jshell> new FileWriter("test.txt", java.nio.charset.StandardCharsets.UTF_8)
$1 ==> java.io.FileWriter@2758fe70

jshell> new FileWriter("test.txt", java.nio.charset.StandardCharsets.UTF_8, true)
$2 ==> java.io.FileWriter@50b494a6
```

## ByteArrayOutputStream class

- `public void writeBytes(byte b[])`
 - 引数で指定されたバイト配列を、この `ByteArrayOutputStream` に書き込みます。

`write(b, 0, b.length)` と同等です。ちょっと書きやすくなりました。

```java
jshell> new ByteArrayOutputStream();
$1 ==>

jshell> $1.writeBytes(new byte[]{0, 1, 2})

jshell> $1.toByteArray()
$2 ==> byte[3] { 0, 1, 2 }
```

## InputStream class

- `public byte[] readNBytes(int len) throws IOException`
 - 指定されたバイト分だけ読み取って、それを格納したバイト配列を返します。
 - 終端の場合、len よりも短いバイト配列を返します。

わざわざバッファを作らなくてすむようになりました。

ただ、何度も呼び出す場合はこれまで通り `read(byte b[])` を使って配列を使い回すように実装したほうがよさそうです。
今回追加されたメソッドだと、毎回配列を作り直してしまうためです。

```java
jshell> new ByteArrayInputStream(new byte[]{0, 1, 2, 3, 4})
$1 ==> java.io.ByteArrayInputStream@1ce92674

jshell> $1.readNBytes(3)
$1 ==> byte[3] { 0, 1, 2 }

jshell> $1.readNBytes(3)
$1 ==> byte[2] { 3, 4 }
```

- `public static InputStream nullInputStream()`
 - 何もしない `InputStream` を返します。

`/dev/null` から読み取るようなストリームです。

```java
jshell> InputStream.nullInputStream()
$1 ==> java.io.InputStream$1@5f2108b5

jshell> $1.readAllBytes()
$2 ==> byte[0] {  }
```

## OutputStream class

- `public static OutputStream nullOutputStream()`
 - 何もしない `OutputStream` を返します。

`/dev/null` に書き込むようなストリームです。

```java
jshell> OutputStream.nullOutputStream()
$12 ==> java.io.OutputStream$1@610694f1

jshell> $12.write(3);
```

## Reader class

- `public static Reader nullReader()`
 - 何もしない `Reader` を返します。

```java
jshell> Reader.nullReader()
$1 ==> java.io.InputStream$1@551aa95a

jshell> $1.read();
$2 ==> -1
```

## Writer class

- `public static Writer nullWriter()`
 - 何もしない `Writer` を返します。

```java
jshell> Writer.nullWriter()
$1 ==> java.io.Writer$1@32709393

jshell> $1.write("ABC")
```

# java.nio

## ByteBuffer class

- `public int mismatch(ByteBuffer that)`
    - この `ByteBuffer` と最初に差異があった相対インデックスを返します。差異がなければ、-1 を返します。

`equals` の逆です。
（ちなみに、`equals` メソッドはこのメソッドを使った判定に書き換えられています）

```java
jshell> ByteBuffer.allocate(3).put(new byte[]{1, 2, 3}).rewind()
$1 ==> java.nio.HeapByteBuffer[pos=0 lim=3 cap=3]

jshell> ByteBuffer.allocate(3).put(new byte[]{1, 9, 3}).rewind()
$2 ==> java.nio.HeapByteBuffer[pos=0 lim=3 cap=3]

jshell> $1.mismatch($2)
$3 ==> 1

jshell> $1.position(3)
$4 ==> java.nio.HeapByteBuffer[pos=3 lim=3 cap=3]

jshell> $2.position(3)
$5 ==> java.nio.HeapByteBuffer[pos=3 lim=3 cap=3]

jshell> $1.mismatch($2)
$6 ==> -1
```

## CharBuffer class

- `public int mismatch(CharBuffer that)`
    - この `CharBuffer` と最初に差異があった相対インデックスを返します。差異がなければ、-1 を返します。

## ShortBuffer class

- `public int mismatch(ShortBuffer that)`
    - この `ShortBuffer` と最初に差異があった相対インデックスを返します。差異がなければ、-1 を返します。

## IntBuffer class

- `public int mismatch(IntBuffer that)`
    - この `IntBuffer` と最初に差異があった相対インデックスを返します。差異がなければ、-1 を返します。

## LongBuffer class

- `public int mismatch(LongBuffer that)`
    - この `LongBuffer` と最初に差異があった相対インデックスを返します。差異がなければ、-1 を返します。

## FloatBuffer class

- `public int mismatch(FloatBuffer that)`
    - この `FloatBuffer` と最初に差異があった相対インデックスを返します。差異がなければ、-1 を返します。

## DoubleBuffer class

- `public int mismatch(DoubleBuffer that)`
    - この `DoubleBuffer` と最初に差異があった相対インデックスを返します。差異がなければ、-1 を返します。

# java.nio.channels

## Selector class

- `public int select(Consumer<SelectionKey> action, long timeout) throws IOException`
- `public int select(Consumer<SelectionKey> action) throws IOException`
- `public int selectNow(Consumer<SelectionKey> action) throws IOException`
    - I/O操作の準備ができているチャネルのキーに対して、アクションを選択して実行します。

さくらばさんの [Java API ダイジェスト Slector クラス](https://www.javainthebox.net/publication/200303JP29/Selector.html) を、これを使った形に書き換えるとこうなります。
キーの操作周りがぐっとシンプルになりました！

```java
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.*;
 
public class NonblockServer {
    private Selector selector;
    private Charset charset = Charset.forName("UTF-16");
         
    public NonblockServer() {
        try {
            selector = Selector.open();
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false); // 非同期モードにする
 
            InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 9000);
            serverSocketChannel.socket().bind(address);
 
            // Selector にアクセプトを登録
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
  
            while (selector.select(this::action) > 0) {
            }
         
            serverSocketChannel.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    private void action(SelectionKey key) {
        try {
            if (key.isAcceptable()) {
                // アクセプトの場合
                ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
                SocketChannel socketChannel = serverChannel.accept();
                socketChannel.configureBlocking(false); // 非同期に変更

                // Selector に読み込みを登録
                socketChannel.register(selector, SelectionKey.OP_READ);
                System.out.println(socketChannel + " connect.");
            } else if (key.isReadable()) {
                // 入力
                SocketChannel channel = (SocketChannel)key.channel();
                sendBack(channel);
            }
        } catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    private void sendBack(SocketChannel socketChannel) throws IOException {
        // データの読み込み
        ByteBuffer buffer = ByteBuffer.allocate(2048);
        socketChannel.read(buffer);
         
        // 読み込んだデータをそのまま送り返す
        buffer.flip();
        System.out.println("Recieve: " + charset.decode(buffer.duplicate()));
        socketChannel.write(buffer);
        socketChannel.close();
    }

    public static void main(String[] args){
        new NonblockServer();
    }
}
```

## SelectionKey class

- `public int interestOpsOr(int ops)`
    - 現在の操作対象に、OR で引数の操作を加えます。
    - デフォルトの実装では、`interestOps(interestOps() | ops)` と同じです。
- `public int interestOpsAnd(int ops)`
    - 現在の操作対象に、AND で引数の操作を加えます。
    - デフォルトの実装では、`interestOps(interestOps() & ops)` と同じです。

SelectionKey の操作がちょっと楽になりました。

# java.nio.files

## Files class

- `public static Path writeString(Path path, CharSequence csq, OpenOption... options) throws IOException`
- `public static Path writeString(Path path, CharSequence csq, Charset cs, OpenOption... options) throws IOException`
    - 指定されたファイルに、文字列を書き込みます。
- `public static String readString(Path path) throws IOException`
- `public static String readString(Path path, Charset cs) throws IOException`
    - 指定されたファイルから、文字列を読み込みます。

ちょっとファイルに文字を書き出すのに これまで面倒な実装が必要でした。
それが、このメソッドのおかげでさくっと実装できるようになりました！

```java
jshell> Files.writeString(Path.of("test.txt"), "テスト")
$1 ==> test.txt

jshell> Files.readString($1)
$2 ==> "テスト"
```

## Path class

- `public static Path of(String first, String... more)`
    - 1つのパス文字列または、連結すると1つのパス文字列を形成する文字列のシーケンスを、`Path` に変換します。
- `public static Path of(URI uri)`
    - 指定された `URI` を `Path` に変換します。

`Paths.get(String, String...)` や `Paths.of(Uri)` と同じ処理です。
`Paths` クラスもこれまでと同様に使えますが、今後はこちらを使ったほうがわかりやすいと思います[^path]

[^path]: 最初からこれがあればよかったのでは…

```java
jshell> Path.of("C:\\", "Windows", "System32")
$1 ==> C:\Windows\System32

jshell> Path.of(new URI("file:/C:/Windows"))
$2 ==> C:\Windows
```

# java.util

## Collection interface

- `default <T> T[] toArray(IntFunction<T[]> generator)`
    - 引数 `generator` を使って配列を作成し、このコレクション内のすべての要素を保持する配列を返します。

コレクションから配列に変換する際に、引数に配列を new する関数を取れるようになりました。

ただ、デフォルト実装が `return toArray(generator.apply(0))`なので、これまで `.toArray(new String[0])` と書いてたのと同等です。
今後、ArrayList などの各クラスがオーバライドして、最初から最適な長さで初期化するようになってくれることを期待したいです。

```java
jshell> List.of("A", "B", "C")
$1 ==> [A, B, C]

jshell> $1.toArray(String[]::new)
$1 ==> String[3] { "A", "B", "C" }

jshell> $1.toArray(new String[0])    // これと同じ
$1 ==> String[3] { "A", "B", "C" }
```

## Optional

- `public boolean isEmpty()`
    - 値が存在しない場合は `true` を返し、そうでない場合は `false` を返します。

`isPresent()` の逆です。

```java
jshell> Optional.ofNullable(null)
$1 ==> Optional.empty

jshell> $1.isEmpty()
$1 ==> true

jshell> Optional.ofNullable("ABC")
$2 ==> Optional[ABC]

jshell> $2.isEmpty()
$2 ==> false
```

## OptionalInt

- `public boolean isEmpty()`
    - 値が存在しない場合は `true` を返し、そうでない場合は `false` を返します。

`Optional` と同じです。

## OptionalLong

- `public boolean isEmpty()`
    - 値が存在しない場合は `true` を返し、そうでない場合は `false` を返します。

`Optional` と同じです。

## OptionalDouble

- `public boolean isEmpty()`
    - 値が存在しない場合は `true` を返し、そうでない場合は `false` を返します。

`Optional` と同じです。

# java.util.concurrent

## TimeUnit

- `public long convert(Duration duration)`
    - 指定された期間を、この単位に変換します。

`Duration#toNanos()` だとオーバーフローしたときに ArithmeticException がスローされますが、このメソッドだとスローされない（Long.MIN_VALUE または Long.MAX_VALUE が返される）という違いがあるそうです。

```java
jshell> import java.time.*

jshell> Duration.ofDays(3)
$1 ==> PT72H

jshell> var unit = TimeUnit.HOURS
unit ==> HOURS

jshell> unit.convert($1)
$2 ==> 72
```

# java.uti.function

## Predicate interface

- `static <T> Predicate<T> not(Predicate<? super T> target)`
    - 与えられた述語(`Predicate<T>`)の否定述語を返します。

`Predicate<T>` は引数をひとつ取って、`boolean` を返す関数です。
その返す `boolean` を逆にしてくれるのがこの関数です。

```java
jshell> Stream.of("A", "", "B", "", "C").filter(String::isEmpty).toArray()
$1 ==> Object[2] { "", "" }

jshell> Stream.of("A", "", "B", "", "C").filter(Predicate.not(String::isEmpty)).toArray()
$2 ==> Object[3] { "A", "B", "C" }
```

# java.util.regex

## Pattern class

- `public Predicate<String> asMatchPredicate()`
    - このパターンが指定された入力文字列と一致するかどうかをテストする述語(`Predicate<T>`)を作成します。

既存の `asPredicate()` だと、内部的に `Matcher#find()` を呼び出す関数、つまり「部分一致」かどうか判定する関数を生成していました。
一方で、この `asMatchPredicate()` だと、内部的に `Matcher#matches()` を呼び出す関数、つまり「完全一致」かどうか判定する関数を生成します。

```java
jshell> Pattern.compile("a*b")
$1 ==> a*b

jshell> $1.asPredicate()
$2==> java.util.regex.Pattern$$Lambda$27/0x00000008000ba440@3891771e

jshell> Stream.of("abc", "aab").filter($2).toArray()
$3 ==> Object[2] { "abc", "aab" }

jshell> $1.asMatchPredicate()
$4 ==> java.util.regex.Pattern$$Lambda$28/0x00000008000e8040@18bf3d14

jshell> Stream.of("abc", "aab").filter($4).toArray()
$5 ==> Object[1] { "aab" }
```

# java.uti.zip

## Deflater class

- `public void setInput(ByteBuffer input)`
    - 圧縮のための入力データを設定します。
- `public int deflate(ByteBuffer output)`
- `public int deflate(ByteBuffer output, int flush)`
    -  入力データを圧縮し、指定されたバイト・バッファに圧縮されたデータを挿入します。

いままで、入出力に `byte[]` しか扱えませんでしたが、今回から `ByteBuffer` も扱えるようになりました。
これにより、余計な変換がなくなって効率がよくなりました。

## Inflater class

- `public void setInput(ByteBuffer input)`
    - 圧縮解除のための入力データを設定します。
- `public void setDictionary(ByteBuffer dictionary)`
    - プリセット・ディクショナリを指定のバイト・バッファに設定します。
- `public int inflate(ByteBuffer output) throws DataFormatException`
    - 指定されたバイト・バッファに圧縮解除したデータを挿入します。

`Deflater` と同じく、いままで入出力に `byte[]` しか扱えませんでしたが、今回から `ByteBuffer` も扱えるようになりました。

# java.net.http

Java 9 で `jdk.incubator.httpclient` として追加されていた HTTP クライアントが、正式な API になりました！
特徴は…

- HTTP/1.1、HTTP/2のサポート
- WebSocket のサポート
- 同期／非同期プログラミングモデルの両方をサポート
- リアクティブストリームとしてリクエスト・レスポンスを処理
- ビルダーパターンの利用

詳しくは、下記の Oracle ブログをご参照ください。
[Oracle Blogs 日本語のまとめ: \[Java\] Introduction to the JDK HTTP Client](https://orablogs-jp.blogspot.com/2018/01/introduction-to-jdk-http-client.html)

# java.security.interfaces

[JEP 324: Key Agreement with Curve25519 and Curve448](http://openjdk.java.net/jeps/324) の対応で、インタフェースやクラスが追加されています。
すみません、よくわかってないのでサラッと JavaDoc の Google 翻訳をコピペして流します。

## RSAKey interface

- `default AlgorithmParameterSpec getParams()`
    - このキーに関連付けられたパラメータを返します。
    - デフォルト実装は、`null` を返します。

## XECKey interface

> An interface for an elliptic curve public/private key as defined by RFC 7748. These keys are distinct from the keys represented by `ECKey`, and they are intended for use with algorithms based on RFC 7748 such as the XDH `KeyAgreement` algorithm. This interface allows access to the algorithm parameters associated with the key.
> 
> RFC 7748で定義されているような楕円曲線の公開鍵/秘密鍵のインタフェースです。これらの鍵は、`ECKey` で表される鍵とは異なり、XDHの `KeyAgreement`アルゴリズムなどのRFC 7748に基づくアルゴリズムで使用することを意図しています。 このインタフェースでは、キーに関連付けられたアルゴリズムパラメータにアクセスできます。

新しく追加されたこのインタフェースには、`AlgorithmParameterSpec getParams()` というメソッドが定義されています。

## XECPrivateKey interface

> An interface for an elliptic curve private key as defined by RFC 7748. These keys are distinct from the keys represented by `ECPrivateKey`, and they are intended for use with algorithms based on RFC 7748 such as the XDH `KeyAgreement` algorithm.
> An XEC private key is an encoded scalar value as described in RFC 7748. The decoding procedure defined in this RFC includes an operation that forces certain bits of the key to either 1 or 0. This operation is known as "pruning" or "clamping" the private key. Arrays returned by this interface are unpruned, and implementations will need to prune the array before using it in any numerical operations.
> RFC 7748で定義されている楕円曲線の秘密鍵用のインタフェースです。これらの鍵は、`ECPrivateKey` で表される鍵とは異なり、XDH `KeyAgreement` アルゴリズムなどのRFC 7748に基づくアルゴリズムで使用することを意図しています。
> XEC秘密鍵は、RFC 7748で説明されているエンコードされたスカラー値です。このRFCで定義されているデコード手順では、キーの特定のビットを1または0に強制する操作が含まれています。この操作は、秘密鍵の「プルーニング」または「クランピング」として知られています。このインタフェースから返される配列はプルーニングされておらず、実装は数値演算で使用する前に配列を整理する必要があります。

新しく追加されたこのインタフェースは、 `XECKey`, `PrivateKey` インタフェースを継承しています。
また、`Optional<byte[]> getScalar();` というメソッドが定義されています。

## XECPublicKey interface

> An interface for an elliptic curve public key as defined by RFC 7748. These keys are distinct from the keys represented by `ECPublicKey`, and they are intended for use with algorithms based on RFC 7748 such as the XDH `KeyAgreement` algorithm.
> An XEC public key is a particular point on the curve, which is represented using only its u-coordinate as described in RFC 7748. A u-coordinate is an element of the field of integers modulo some value that is determined by the algorithm parameters. This field element is represented by a BigInteger which may hold any value. That is, the BigInteger is not restricted to the range of canonical field elements.
> RFC 7748で定義されている楕円曲線の公開鍵用のインタフェースです。これらの鍵は、`ECPublicKey` で表される鍵とは異なり、XDH `KeyAgreement` アルゴリズムなどのRFC 7748に基づくアルゴリズムで使用することを意図しています。
> XEC公開鍵は、カーブ上の特定の点であり、RFC 7748に記述されているU座標のみを使用して表されます.U座標は、アルゴリズムパラメータによって決定されるある値を法とする整数フィールドの要素です。 このフィールド要素は、任意の値を保持できるBigIntegerで表されます。 つまり、BigIntegerは正規のフィールド要素の範囲に限定されません。

新しく追加されたこのインタフェースは、 `XECKey`, `PublicKey` インタフェースを継承しています。
また、`BigInteger getU();` というメソッドが定義されています。

# java.security.spec

## NamedParameterSpec class

> This class is used to specify any algorithm parameters that are determined by a standard name. 
> このクラスは、標準名によって決定されるアルゴリズムパラメータを指定するために使用されます。

このクラスには、定数として `X25519` と `X448` が定義されています。

## PSSParameterSpec class

- `public static final int TRAILER_FIELD_BC = 1;`
    - PKCS#1 （RSA暗号標準）で定義されている `TrailerFieldBC` 定数です。

## RSAKeyGenParameterSpec class

- `public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent, AlgorithmParameterSpec keyParams)`
    - 指定されたキー・サイズおよび公開指数値、キーパラメータから新しいRSAParameterSpecオブジェクトを構築します。
- `public AlgorithmParameterSpec getKeyParams()`
    - キーに関連付けるパラメータを返します。

`RSAKeyGenParameterSpec` が `AlgorithmParameterSpec` （暗号パラメータの透明な仕様）を指定できるようになりました。

## RSAPrivateKeySpec class

- `public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent, AlgorithmParameterSpec params)`
    - 新しい `RSAPrivateKeySpec` を作成します。
- `public AlgorithmParameterSpec getKeyParams()`
    - キーに関連付けられたパラメータを返します。存在しない場合は`null`になります。

`AlgorithmParameterSpec` （暗号パラメータの透明な仕様）を指定できるようになりました。

## RSAPublicKeySpec class

- `public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent, AlgorithmParameterSpec params)`
    - 新しい `RSAPublicKeySpec` を作成します。
- `public AlgorithmParameterSpec getKeyParams()`
    - キーに関連付けられたパラメータを返します。存在しない場合は`null`になります。

`AlgorithmParameterSpec` （暗号パラメータの透明な仕様）を保持するようになりました。

## RSAMultiPrimePrivateCrtKeySpec class

- `public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger primeP, BigInteger primeQ, BigInteger primeExponentP, BigInteger primeExponentQ, BigInteger crtCoefficient, RSAOtherPrimeInfo[] otherPrimeInfo, AlgorithmParameterSpec keyParams)`
    - PKCS#1 v2.1に定義されたmodulus、publicExponent、privateExponent、primeP、primeQ、primeExponentP、primeExponentQ、crtCoefficient、otherPrimeInfo、およびkeyParamsを指定し、新しいRSAMultiPrimePrivateCrtKeySpecを作成します。

`AlgorithmParameterSpec` （暗号パラメータの透明な仕様）を保持するようになりました。

## RSAPrivateCrtKeySpec class

- `public RSAPrivateCrtKeySpec(BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger primeP, BigInteger primeQ, BigInteger primeExponentP, BigInteger primeExponentQ, BigInteger crtCoefficient, AlgorithmParameterSpec keyParams)`
    - PKCS#1に定義されたmodulus、publicExponent、privateExponent、primeP、primeQ、primeExponentP、primeExponentQ、crtCoefficient、およびkeyParamsを指定し、新しいRSAPrivateCrtKeySpecを作成します。

`AlgorithmParameterSpec` （暗号パラメータの透明な仕様）を保持するようになりました。

## XECPrivateKeySpec class

> A class representing elliptic curve private keys as defined in RFC 7748, including the curve and other algorithm parameters. The private key is represented as an encoded scalar value. The decoding procedure defined in the RFC includes an operation that forces certain bits of the key to either 1 or 0. This operation is known as "pruning" or "clamping" the private key. All arrays in this spec are unpruned, and implementations will need to prune the array before using it in any numerical operations.
> 曲線や他のアルゴリズムパラメータを含む、RFC 7748で定義されている楕円曲線の秘密鍵を表すクラス。 秘密鍵は、符号化されたスカラー値として表されます。 RFCで定義されているデコード手順には、キーの特定のビットを1または0に強制する操作が含まれています。この操作は、秘密鍵の「プルーニング」または「クランピング」として知られています。 この仕様のすべての配列はプルーニングされておらず、実装は数値演算で使用する前に配列を整理する必要があります。

## XECPublicKeySpec class

> A class representing elliptic curve public keys as defined in RFC 7748, including the curve and other algorithm parameters. The public key is a particular point on the curve, which is represented using only its u-coordinate. A u-coordinate is an element of the field of integers modulo some value that is determined by the algorithm parameters. This field element is represented by a BigInteger which may hold any value. That is, the BigInteger is not restricted to the range of canonical field elements.
> 曲線や他のアルゴリズムパラメータを含む、RFC 7748で定義されている楕円曲線の公開鍵を表すクラス。 公開鍵は、曲線上の特定の点であり、そのU座標のみを使用して表されます。 U座標は、アルゴリズムパラメータによって決定されるある値を法とする整数のフィールドの要素です。 このフィールド要素は、任意の値を保持できるBigIntegerで表されます。 つまり、BigIntegerは正規のフィールド要素の範囲に限定されません。

# まとめ

大きな追加は HTTP クライアントと暗号関連ですね。
それ以外は小さな追加ですが、今までめんどくさかったのが簡単にかけるようになって、とてもいい感じです！

ぜひ Java 11 を積極的に使っていきましょう:thumbsup: