[Java9 新機能] jshell入門

# 1. Introduction

<img width="350" alt="スクリーンショット 2016-08-06 16.36.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/6e438d43-c76f-7e3b-6fa1-ab84a374d2be.jpeg">

JDK9のリリースまで残すところあと半年ちょっとになりました。
JDK9の新機能、 `Project Jigsaw` によるモジュール化が取り上げれることが多いですが、
Javaの `REPL` 、 **jshell** が搭載されたのが気になりました。

今回は**jshell**を触るまでの環境構築と事項してみた所感を書いていきます。

* 筆者環境はMac OS Xです

## 1.1 REPL??

読んで字のごとく、

* **R** : Read 読んで
* **E** : Eval 評価して
* **P** : Print 出力して
* **L** : Loop 繰り返す

一行書いて実行、一行書いて実行、一行書いて... を繰り返せます。

![jdk9-repl.png](https://qiita-image-store.s3.amazonaws.com/0/103247/ed86c0db-a857-f901-76e1-1ce9aeec0dc0.png)


## 1.2 jshell??

他言語ではこのREPLという仕組みが一般的で、
RubyやScalaには標準で付属しています。
いよいよJavaにもこのREPLが導入されました。

そもそもJavaには言語の完成度は置いておいて、**実行までの手順の複雑さ** がありました。
北米の情報系の大学でも、入学試験でJavaではなくPythonが用いられることが多く、理由の一つに **実行までの煩わしさ** が含まれているそうです。

Java言語が容易に実行できる環境 (=jshell) が普及すればJavaももっと普及するんですかね。(どうですかね？)

# 2. Download

1. こちらから [Open JDK9 Early Access Releases](https://jdk9.java.net/download/) が入手できます
1. ダウンロードしたらインストーラーを起動してインストール

<img width="621" alt="スクリーンショット 2016-08-06 16.36.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/0c31f19e-777e-a441-6e63-7a73837ec74c.png">


これで完了です

# 3. Hello World

とりあえずHello World出してみます。

## 3.1 Start-up **jshell** !!

インストールが完了したら

`/Library/Java/JavaVirtualMachines/ `

配下にインストール済みのJDKの一覧があるので

`jdk-9.jdk` があるのを確認します。

<img width="783" alt="スクリーンショット 2016-08-07 18.17.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/43458bf7-402b-72ec-0232-10464e40828f.png">

jdk9配下に、

`jdk-9.jdk/Contents/Home/bin/`

binの配下に、

`jshell` がありますので起動します。
<img width="1191" alt="スクリーンショット 2016-08-07 18.19.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/3c577c6b-2475-f4ed-afa5-61201fa0d470.png">

<img width="715" alt="スクリーンショット 2016-08-07 18.20.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/b4f27415-60b7-6d40-f3e0-b0f691d48b3c.png">

無事起動しました!!!!
以前試したときは英語でしたが、日本語でwelcomeメッセージが表示されました!!

## 3.2 Hello World

Hello Worldしてみます！

### 3.2.1 そのまま
<img width="564" alt="スクリーンショット 2016-08-07 18.21.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/3d3bc310-76f9-3659-6440-d8ad196584c6.png">

一番シンプルな方法です、**タブ補完が効く**のでスイスイ入力できました。
ちなみ**にセミコロン無し**で実行できました。

### 3.2.2 変数

<img width="504" alt="スクリーンショット 2016-08-07 18.23.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/91e0eab8-cfc1-cb19-f011-4525ba3b6a36.png">

一度変数に格納してから出力しました。
２行目では**変数名のタブ補完**が効いたのが快適でした。

### 3.2.3 /open

後述しますが、オプションコマンドの **/open** を使うことで外部ファイルを読み込んで実行できます。

<img width="475" alt="スクリーンショット 2016-08-07 18.24.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/2f5aee50-137e-dec5-d802-f247ae7e20bf.png">


```java:Hello.java
System.out.println("Hello World")
```

ファイルを読み込めるのであれば、スクリプトとして実行できるかな？とおもったのですが。
読み込んだファイルを一行ずつ評価してるようなので、以下のjavaファイルでは何も実行されませんでした。

<img width="487" alt="スクリーンショット 2016-08-07 18.25.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/fd2377ea-c55b-9f52-0435-7600aada5f65.png">


```java:Hello.java
class Hello {
  public static void main(String[] args) {	
    System.out.println("Hello World");
  }
}
```

というか、**一行ずつ読まれてるんなら読み込むファイルはテキストファイルでもいいのか？**
と、思ったので適当な拡張子で読み込んでみました。

<img width="466" alt="スクリーンショット 2016-08-07 18.26.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/53f1d1e3-2b86-bd8f-52e6-a22ad95a6445.png">

```java:Hello.txt
System.out.println("Hello World")
```

**読めました。**

読み込んだ先のファイルを一行ずつ実行するみたいですね。拡張子は`.java`じゃなくても良さそうです。

# 4. もうちょっと触ってみる

単純に一行ずつコードを試して見る。以外の使い方ができそうなので少しだけ見てみました。

## 4.1 コマンド

Welcomeメッセージで表示される `/help` コマンドで使用可能なコマンドの一覧が確認できます。

| コマンド | 説明 |
|----------|------|
| **/list** |   入力したソースをリストします   |
|    **/edit**      | 名前またはIDで参照されるソース・エントリを編集します     |
|    **/drop**      | 名前またはIDで参照されるソース・エントリを削除します     |
|    **/save**      | ファイルにスニペット・ソースを保存します     |
|    **/open**      | ソースの入力としてファイルを開きます     |
|    **/vars**      | 宣言された変数およびその値をリストします     |
|    **/methods**      | 宣言されたメソッドおよびその署名をリストします     |
|    **/types**      | 宣言された型をリストします     |
|    **/imports**      | インポートされたアイテムをリストします     |
|    **/exit**      | exit jshell |
|    **/reset**      |  reset jshell    |
|    **/reload**      | リセットして関連する履歴をリプレイします     |
|    **/classpath**      |  クラスパスにパスを追加します    |
|    **/history**      | 入力した内容の履歴    |
|    **/help**      |  jshellに関する情報を取得します    |
|    **/set**      |  jshell構成情報を設定します    |
|    **/retain**      |  後続のセッションに対してjshell構成情報を保持します    |
|    **/?**      | jshellに関する情報を取得します     |
|    **/!**      | 最後のスニペットを再実行します     |
|    **/< id >**      | IDでスニペットを再実行します     |
|    **/-< n >**      |  n回前のスニペットを再実行します    |



いろいろありますね。
なんかいろんなことできそうですが、余裕があれば別記事でまとめたいと思います。

別件ですが、`/help` を見るまで**jshellの終了のさせ方がわからずパニックになりました。** 
`/exit` で終了できますが、コマンドが全部`/`から始まるとは..

## 4.2 クラス作ってみる

一行ずつ実行してもいいですが、クラスを宣言して呼び出す。といった使い方もしてみます。

<img width="319" alt="スクリーンショット 2016-08-07 17.30.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/cdb4a8f1-0f56-962a-d329-b5e6ced0d45e.png">

`{}` 中括弧を閉じるまで入力が続きます。

<img width="624" alt="スクリーンショット 2016-08-07 17.32.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/2dd2fb8a-a899-51a8-ad74-68c72572a8e2.png">

引数を受け取って、出力するだけの簡単なクラスです。

<img width="640" alt="スクリーンショット 2016-08-07 17.34.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/048c8ecc-3a01-d0fc-0b96-ea1539dcdadf.png">

無事に呼び出せました！！

さっきのコマンド **`/types`** で作成したクラスも確認できます。

<img width="271" alt="スクリーンショット 2016-08-07 17.35.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/103247/bcc6a88f-f28e-3af0-e694-bebfbcc0172b.png">


# 5. 所感

今回はjshellの触りだけ体験してみました！！
正直な感想は、**「業務レベルで使用することはあるのか？」**です。

1. タブ補完でコードを入力していくことができるが、IntelliJ IDEAなどの強力なIDEの補完にはもちろん及ばない。やや入力がストレス。
1. 実行時まで構文エラーに気付けない => Javaでやらなくて良くない？
2. 
と、思いました。Paiza ioのようなオンライン実行環境ありますし。

ただ、**Javaを新しく始める。**といったような場合には、今までのように
1. JDKインストール
2. Eclipseインストール
3. パッケージ作成
4. クラス作成
5. Hello World

といった煩わしい手順を踏まずに、
1. JDKインストール
2. **jshell起動**
3. Hello World

というように**非常に容易にJavaコードの実行**ができます。
これは**Javaの入門書が9以降大幅な書き換えが行われるのか？**と、思えるレベルのインパクトを感じました。

また、コマンドもあまり触ってないので今回触ってないもっと便利な使い方も確実に存在します。
もうちょっと触ってみて、まだ便利そうな使い方があればまた記事にしてみたいと思います！
コメントでもご指摘などいただけると幸いです！

最後までご覧いただきありがとうございました！