Java9の新機能紹介

<a hfref="https://adventar.org/calendars/2326">バルテックアドベントカレンダー2017</a>用記事です。
CNN、RNNを使用して遊んでみようかと思っていたけど、担当日が１２月２日で余り期間がなかったので別ネタで行こうかと思う。

2017年9月22日 Java 9がついにリリースされました。
が、リリースはされたけど、そういやお家PCにいれて無いし遊んでもいねぇなぁと思ったので9の新機能を試すついでに紹介していきたいと思います。

公式の？機能紹介文
http://www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-JA17-Java9Features.pdf

とりあえずダウンロードして解凍してパス通して「java -version」叩いて見た。

![Screenshot from 2017-12-02 14:01:49.png](https://qiita-image-store.s3.amazonaws.com/0/106422/9d6b63fa-90ac-09f8-4f93-cebb6ccc6363.png)

うん、OK！！

#新機能１　「JShell」

今までJavaのコード書いている時に「あれ？文字列の末尾から3文字取り出すのって3だっけ？」とかちょっと挙動確認したいときにわざわざTest.javaなんか作ってコード書いて実行していたけどこれからはJshellから気軽に試せるようになった。

## 起動
jshellって叩けば起動する。

![Screenshot from 2017-12-02 14:10:55.png](https://qiita-image-store.s3.amazonaws.com/0/106422/202de9a9-b7fc-9f4a-b937-0ead85ddfdb1.png)

「あれ？文字列の末尾から3文字取り出すのって3だっけ？-3だっけ」って試すときはメインメソッドなぞ書かずに

 System.out.println("123456".substring(3));

ってかくだけで行ける！！

![Screenshot from 2017-12-02 14:23:36.png](https://qiita-image-store.s3.amazonaws.com/0/106422/dfc25e13-74d9-8cc3-7f53-8b35c723f1eb.png)

おおお！楽！

んじゃクラスとかって定義できんのか？と思って実験

![Screenshot from 2017-12-02 14:28:14.png](https://qiita-image-store.s3.amazonaws.com/0/106422/2632dba4-1424-f2e6-6401-22e8f894fd2b.png)

おおぉ！できる！

じゃあスクリプト化できるのか？と思って実験

とりあえず適当にいつものシェルスクリプトっぽく書いてみた

![Screenshot from 2017-12-02 14:36:21.png](https://qiita-image-store.s3.amazonaws.com/0/106422/45c70f79-4f74-9dfc-93d0-48882463bb3c.png)

実行！！

![Screenshot from 2017-12-02 14:37:39.png](https://qiita-image-store.s3.amazonaws.com/0/106422/3a790360-dd41-5215-ecbf-332cf960cd35.png)

う〜ん、一応実行されたけど・・・正規のルートでは無いってかんじか

ちょっと調べた結果ファイルに記述されたjshellは「/open」で食わせる感じ見たい

先頭の「#!」文を消して・・・
![Screenshot from 2017-12-02 14:42:33.png](https://qiita-image-store.s3.amazonaws.com/0/106422/1670aecd-5484-6e4f-911a-1581e97e4b91.png)

実行！！

![Screenshot from 2017-12-02 14:45:13.png](https://qiita-image-store.s3.amazonaws.com/0/106422/179e2a2a-ebed-b953-4746-91586b827403.png)

実行された！！

jshellはただの実験場だと漠然と思ってたけど、スクリプト化できると考えると色々応用できそうですね
（多分jarファイルなども読み込ませて呼べたりするんだろうしコンパイルがいらないjavaと考えるとツールなんか作るときに最適かも？）


#新機能２ コレクションのファクトリ・メソッド

不変のListや、Mapをまとめて作成することができる。

![Screenshot from 2017-12-02 15:02:38.png](https://qiita-image-store.s3.amazonaws.com/0/106422/0bade33a-1fad-a20d-6dd2-e2dba35ed10b.png)

出来た！

そういや不変と言っているということは・・・addしようとすると怒られる？

![Screenshot from 2017-12-02 15:06:17.png](https://qiita-image-store.s3.amazonaws.com/0/106422/fd34aa0e-25f2-21dc-7e89-efa60bb9c3e7.png)

ちゃんと怒られた

これでクラス変数のLISTにstaticイニシャライザや、コンストラクタでだらだらList初期化書かずに済むね

#新機能３ クラスパス地獄からの脱却（Jigsawプロジェクト）

<a href="http://openjdk.java.net/projects/jigsaw/quick-start">クイックスタート</a>をまんま実行してみる

コードを書いて・・・

![Screenshot from 2017-12-02 16:12:10.png](https://qiita-image-store.s3.amazonaws.com/0/106422/66e4e6b3-2d70-29a5-6bc5-aeb56263131a.png)

コンパイルして・・・実行！！

![Screenshot from 2017-12-02 16:13:25.png](https://qiita-image-store.s3.amazonaws.com/0/106422/bda94fac-8a96-e984-7223-f8c8c3f9bb7c.png)

うまくいっているが、さすがに旨味を感じない・・・次！！

![Screenshot from 2017-12-02 16:22:55.png](https://qiita-image-store.s3.amazonaws.com/0/106422/54e9799f-fd24-2e8d-c9ff-a754dfe7f9b4.png)

com.greetings -> com.astro　という依存関係となっている。
コンパイルをしてみる。

![Screenshot from 2017-12-02 16:25:30.png](https://qiita-image-store.s3.amazonaws.com/0/106422/91330176-dd4a-1aa9-4ee7-6436fb5ce725.png)

com.astroをコンパイルしてから、com.greetingsをコンパイルしている。
よく見てみると、com.greetingsはcom.astroに依存しているにも関わらず、com.greetingsコンパイル時にクラスパスを指定していない。

では実行してみる。

![Screenshot from 2017-12-02 16:30:31.png](https://qiita-image-store.s3.amazonaws.com/0/106422/38e66420-d344-e530-ab3f-2f1ef0474a5d.png)

おおおおお！クラスパスを指定していないにも関わらず、きちんと実行されている

## 依存モジュールの解決

module-info.javaに公開するモジュール名と、依存するモジュール名を記述して依存関係を指定するようです。


**com.astroの「module-info.java」**
「exports」で「公開」するモジュールが定義されている。

`module org.astro {
   exports org.astro;
}`

**com.greetingsの「module-info.java」**
「requires」で「依存」するモジュールが定義されている。
`
module com.greetings {
    requires org.astro;
}
`

うん、シンプルでわかりやすい！

## まとめてコンパイル

前の例では、モジュールcom.greetingsとモジュールorg.astroが別々にコンパイルされていたが、1つのjavacコマンドで複数のモジュールをコンパイルすることもできるらしい

![Screenshot from 2017-12-02 16:35:03.png](https://qiita-image-store.s3.amazonaws.com/0/106422/e2e6f320-6ef4-dbcb-7b6a-de4c7fe2016c.png)

## jarに固める

![Screenshot from 2017-12-02 16:41:02.png](https://qiita-image-store.s3.amazonaws.com/0/106422/63227ac7-fa62-25ec-82aa-b366ab0372e9.png)

com.greetingsを作るときに「--main-class=com.greetings.Main」を指定している。
これはこの後にjarから実行する際に、マニフェストファイルのかわりに実行クラスを指定しているものかと思われる。


## jarに固めたモノを実行

![Screenshot from 2017-12-02 16:43:48.png](https://qiita-image-store.s3.amazonaws.com/0/106422/b89304c2-21a0-785b-f62b-81e938f8a08e.png)

jarが入ったディレクトリを指定してどのモジュールを実行するか指定するだけでMainクラスがきちんと実行されている。

## jarの詳細情報を表示

jar --describe-moduleを使用するとjarの詳細情報がみれるようです。

![Screenshot from 2017-12-02 16:47:18.png](https://qiita-image-store.s3.amazonaws.com/0/106422/a8a67cd9-ab41-664e-4bbd-fedde746087c.png)


# まとめ
Java9にはまだまだ新機能が有ります。（個人的に中核的なものは上記に書いたモノだと思うけど）
我々が業務で使うにはちょっと先だと思うけど、今のうちに遊んでおいて将来ドヤ顔するのも一興かと思います。
（Jigsawなんかはまだかなり奥が深いと思うので書籍化されるのを心待ちにしているのだけれど、もうちょっと先かな？）