Java9の新機能とサンプルコード

[ブログ記事](http://mrdshinse.hatenablog.com/entry/2017/02/14/190243)の転載です。

> Java9リリースが2017年7月に迫ってきたということで、
Java9で新しく出来るようになることをサンプルコードと一緒に紹介していきます。

> なお、すべてリリース前の情報ですので、
実際にリリースされるJava9では異なる場合があるので注意してください。

Java10リリースが迫ってきましたね、リンク貼っておきます。
[Java 10新機能まとめ](https://qiita.com/nowokay/items/d9bc4b3f715d17c2830d)

# 目次
1. JShell
2. 不変List/Set/Map用のファクトリメソッド
3. Interface内のprivateメソッド
4. モジュールシステム
5. Process APIの改善
6. try-with-resourceの改善
7. CompletableFuture APIの改善
8. リアクティブストリーム
9. 匿名クラスでのダイアモンド演算子
10. Optionalクラスの改善
11. Stream APIの改善
12. @Deprecatedアノテーションの強化
13. HTTP2クライアント
14. Multi-Resolution Image API
15. その他もろもろ


## JShell
REPL環境です。
コマンドラインからJavaを実行して、
APIの確認やら簡単なテストができるようになりました。

```java
C:\>jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro

jshell> String helloWorld = "Hello World"
helloWorld ==> "Hello World"

jshell> System.out.println(helloWorld + "!!" )
Hello World!!
```

## 不変List/Set/Map用のファクトリメソッド
タイトルの通りです。
Guava(Googleの共通処理ライブラリ)風にList/Set/Mapを作れるようになりました。

```java
jshell> List emptyImmutableList = List.of();
emptyImmutableList ==> []
jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}
```

## Interface内のprivateメソッド
Java8ではInterfaceにdefaultメソッドとstaticメソッドが定義できるようになりました。
Java9では、privateメソッドも定義できるようになります。

```java
public interface Card{
  private Long createCardID();
  private static void displayCardDetails();
}
```

## モジュールシステム
Jigsawプロジェクトと呼ばれていたやつです。
公開するAPI、非公開APIをmodule-info.javaに定義することが出来るようになりました。

[こちら](http://qiita.com/hashiwa/items/9ae1f8ad8d2e8f916664)の記事にサンプルコードが載っています。

## Process APIの改善
以下のクラスが追加されました。

+ java.lang.ProcessHandle
+ java.lang.ProcessHandle.Info

```java
 ProcessHandle currentProcess = ProcessHandle.current();
 System.out.println("Current Process Id: = " + currentProcess.getPid());
```

## try-with-resourceの改善
Java8までのtry-with-resource文は、
try節の中でクラスを宣言することが必須だったのですが、
これが不要になりました。

```java
void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}
```

## CompletableFuture APIの改善
CompletableFuture APIに、

+ 遅延
+ タイムアウト
+ いくつかのユーティリティメソッド
+ より良いサブクラス化をサポート

等の機能が追加されました。

```java
Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
```

## リアクティブストリーム
非同期処理/並列処理/スケーラブルなアプリ開発をすすめるために、
Publish/Subscribe Frameworkが追加されました。
Akka等にある仕組みです。

+ java.util.concurrent.Flow
+ java.util.concurrent.Flow.Publisher
+ java.util.concurrent.Flow.Subscriber
+ java.util.concurrent.Flow.Processor

[こちら](https://community.oracle.com/docs/DOC-1006738)にサンプルコードが載っています。

## 匿名クラスでのダイアモンド演算子
詳細がわからなかったので省略。

## Optionalクラスの改善
Optionalクラスにいろいろ追加されました。

+ public void ifPresentOrElse(Consumerl<? super Tl> action, Runnable emptyAction)
+ public Optional`<T>` or(Supplier<? extends Optional<? extends T>> supplier)
+ Optional::stream

Optional::streamをStream#flatMapに渡すことで、
包まれていたクラスのStreamに変換できるみたいです。

```java
Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)
```

## Stream APIの改善
Scala同様に書けるtakeWhileメソッド、dropWhileメソッドが追加されました。

```java
jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                 .forEach(System.out::println);
1
2
3
4
```

## @Deprecatedアノテーションの強化
廃止予定なのか？(forRemoval)
いつ廃止するのか？(since)
といった情報が与えられるようになったようです。

## HTTP2クライアント
こちらはインキュベーション機能に格下げになってしまったようです...。
[参考](https://www.infoq.com/jp/news/2017/02/java9-rampdown-phase-start)
>HTTP/2 ClientはJava 9に含まれるが、デフォルトではアクセスできないだろうということだ。機能はjdk.incubatorというプレフィクスのモジュールにパッケージされる。それにアクセスする開発者は明示的に--add-modフラグを使う必要がある。しかし、もしこうすることを選択すると、インキュベーション機能は標準APIの一部ではなく、それゆえにいつでも修正されることを考慮する必要があるだろう。

```java
jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new URI("http://google.com")
uri ==> http://google.com

jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " + response.body(asString()))
```

## Multi-Resolution Image API
java.awt.imageパッケージにMultiResolutionImageインターフェースが追加されたそうです。

詳細は[公式doc](http://download.java.net/java/jigsaw/docs/api/java/awt/image/MultiResolutionImage.html)で

## その他もろもろ
他にも

+ GC (Garbage Collector)の改善
+ Stack-Walking API
+ Filter Incoming Serialization Data
+ Applet APIの非推奨(Deprecate)
+ Indify String Concatenation
+ Method Handlesの強化
+ Java Platform Logging API and Service
+ コンパクトなStrings
+ Nashorn用Parser API
+ Javadocに検索機能
+ JavadocをHTML5に

等があるそうです。

## 参考
[Java 9 Features with Examples](http://www.journaldev.com/13121/java-9-features-with-examples#java-9-core)