Java7からJava9までの新機能を一挙にキャッチアップ

# はじめに
この2年ほどTypeScriptでフロントエンド開発ばかりやっております。
以前はJavaを使ったサーバサイド開発も行っていたのですが最後に使ったバージョンはJava 7です。
2017年9月にJava 9がリリースされ、完全に置いていかれている感じになってきたのでJava7からJava9までで
変わった点を一挙にキャッチアップしてみます。

# Java 8の主要な新機能
Java8は2014年3月にリリースされました。Java8ではラムダ式やStreamAPIなど、より簡潔にコードをかける機能が追加されました。
Java8の新機能はコードがスマートに書けるようになり、Javaが少し洗練された感じです。

## ラムダ式
Javaもやっとラムダ式が使えるようになりました。

```java:java7
		// 無名クラスを使用する
		Arrays.sort(array, new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				return s1.getAge() - s2.getAge();
			}
		});
```

Java8では以下のようにアロー演算子を使って書けるようになりました。
ラムダ式の書き方はいろいろありますが、ここでは省略します。

```java:java8
		// ラムダ式を使用できる
		Arrays.sort(array, (s1, s2) -> s1.getAge() - s2.getAge());
```
関数インタフェースを引数にとるメソッドを書くことでユーザがラムダ式を使えるメソッドを定義することもできます。


## Stream API
配列などを扱う便利なAPIが追加されました。
Java7まではforなどを使っていた処理がメソッドチェーンで簡潔に記述することができるようになりました。

```java:java7
String[] list = new String[] {
				"ABC", "CDE", "EFG"
		};

		// Java7 for分を使用する
		String target = "";
		for (String str : list) {
			if (str.contains("C")) {
				target += str;
			}
		}
```

```java:java8
		Optional<String> result = Arrays.stream(list).filter(s -> s.contains("C")).reduce((v1, v2) -> v1 + v2);
```

## Optional
Optionalはnullをうまく扱うためのAPIです。nullをラップしてnullかもしれない場合の処理を書けるようになります。

例えばJava7までは以下のようにnullチェックしていたコードが

```java:java7
		String str1 = "hoge";
		if (str1 != null) {
			System.out.println(str1);
		}
```

Optionalを使用すると以下のようにすっきり書けます。

```java:java8
		Optional<String> str2 = Optional.ofNullable("hoge");
		str2.ifPresent(x -> System.out.println(x));
```

また以下のようなコードも

```java:java7
		String str1 = "hoge";
		if (str1 != null) {
			System.out.println(str1);
		} else {
			System.out.println("nullです");
		}
```

以下のようにすっきり書けます。

```java:java8
		String str2 = Optional.ofNullable("hoge").orElse("nullです");
		System.out.println(str2);
```

## Date and Time API
java8になって新しくjava.timeパッケージが追加され、ISO8601をベースとした日時を扱うさまざまなクラスが追加されました。
最低限覚えておきたいAPIは以下です。

| 新API |  概要 |
|:------|-----|
|LocalDateTime| タイムゾーンのない日時|
|ZonedDateTime| タイムゾーン付きの日時|
|DateTimeFormatter|フォーマッタ。SimpleDateFormatに相当|





## interface
interfaceにデフォルトの実装を持てるようになりました。
以下のようにメソッドとstaticメソッドを書けます。デフォルトメソッドは実装クラスでオーバーライドすることができます。


```java:java8
public interface IDefaultSample {

	default void Print(String value) {
		System.out.println(value);
	}

	public static void Hello() {
		System.out.println("hello");
	}
}
````
## タイプアノテーション
java7まではクラスやメソッドの宣言にしか使用できなかったアノテーションですが、java8から
（変数やジェネリックスの）型にも使用できるようになりました。

# Java 9の主要な新機能
次にjava8 から java9の変更点です。一番大きな追加はモジュール化ではないでしょうか。
その他、機能改善が多くあるようです。

## モジュール化「Project Jigsaw」
複数のクラスをまとめてモジュールという単位で依存関係・公開設定・バージョン設定等ができるようになりました。

モジュールの定義は「module-info.java」というファイルを記述することで簡単に行えるようです。
[こちら](http://openjdk.java.net/projects/jigsaw/quick-start)のプログラムを参考にしました。

module-info.javaには以下の通りモジュールの宣言と公開するパッケージを宣言します。
ここではorg.astroモジュールの宣言でorg.astroパッケージを公開する設定です。

**宣言の説明**
 - module ：モジュールの宣言
 - exports ：公開するパッケージを指定


```java:src/org.astro/module-info.java
module org.astro {
    exports org.astro;
}
```
```java:src/org.astro/org/astro/World.java
package org.astro;
  public class World {
    public static String name() {
        return "world";
    }
}
```

次は依存するモジュールを指定する方法です。
com.greetingsモジュールは内部のクラスでorg.astroモジュールを使用しているため
この宣言が必要になります。

**宣言の説明**
 - requires ：依存するモジュールを指定


```java:src/com.greetings/module-info.java
module com.greetings {
    requires org.astro;
}
```

```java:src/com.greetings/com/greetings/Main.java
package com.greetings;
import org.astro.World;
public class Main {
    public static void main(String[] args) {
        System.out.format("Greetings %s!%n", World.name());
    }
}
```

くわしくは[こちら](http://openjdk.java.net/projects/jigsaw/)に記載されています。

## JShell
javaのREPLであるjshellが搭載されました。
REPLとは**R**(Read)読んで**E**(Eval)評価して**P**(Print)出力を**L**(Loop)繰り返すことです。
ほかの言語では搭載されているものもあります。

使い方はJDKにパスを通すかJDKまで移動し、jshellコマンドを実行します。

これで以下のようにJavaの構文が即時実行できます。
あまり使い道を思いつきませんが、ちょっとしたコードを試すのには良いかもしれません。

![SnapCrab_コマンド プロンプト - jshell_2017-12-17_15-14-15_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/171118/311a0d2c-b663-9e19-a57b-c767206be433.png)


## interfaceにprivateメソッド
java8で追加された、interfaceにdefaultメソッド、staticメソッドが記述できるようになった機能に追加でprivateメソッドが記述できるようになりました。

## Stream API機能追加
java8で追加されたStream APIにtakeWhile、dropWhileメソッドが追加されました。

## Reactive Streams
非同期ストリームを実現するためPublish・Subscribeモデルを採用したFrameworkが追加されました。
ITproの[こちらの記事](http://itpro.nikkeibp.co.jp/atcl/column/15/120700278/061900041/)に詳しく解説されています。

# さいごに
その他たくさんの変更点が含まれていますが、今回は駆け足で主要な変更点について見てきました。