前回からProject Kullaを紹介しています。簡単におさらいしておきましょう。Project Kullaでは、JavaのREPLツールであるJShellを提供しています。JShellを使用すれば、クラスを定義せずとも、Javaのコードを行単位で実行できます。JShellで実行するコードは、Javaコードの断片ということで、スニペットと呼ばれています。

 今回は、さらにJShellの使い方を紹介していきます。

メソッド・クラスの定義

 前回は変数の定義や、クラス、メソッドを使用するスニペットを例にしてきました。JShellではそれだけでなく、メソッドやクラスを定義できます。しかも、変数と同様に、クラスを作成しなくてもメソッドの定義ができます。

 ここでは、例として階乗を計算するメソッドを定義してみましょう。

jshell> long fractorial(long x) {
   ...>   return LongStream.rangeClosed(1, x).
   ...>                     reduce(1, (s, t) -> s * t);
   ...> }
|  次を作成しました: メソッド fractorial(long)

jshell>

 メソッドも1行で定義しますが、前回紹介したように文の途中で改行した場合、次行に続けて記述することができます。階乗は、LongStreamインタフェースのreduceメソッドを使用して計算しています。

 fractorialメソッドは定義できたので、さっそく使ってみましょう。

jshell> long f = fractorial(10)
f ==> 3628800

jshell> System.out.println(f)
3628800

jshell>

 fractrialメソッドは、単にメソッドをコールするだけで使用できます。Javaではインスタンスメソッドであればオブジェクト、クラスメソッドであればクラスが必要だったことに比べると、JShellでのメソッドの定義はちょっと違和感がありますね。

 しかし、簡単にメソッドを定義でき、使うのも容易であるので、ちょっと試すには便利です。

 同じように、クラスを定義できます。ここでは、複素数を表すComplexクラスを作ってみましょう。

jshell> class Complex {
   ...> double r; double i;
   ...> Complex(double r, double i) { this.r = r; this.i = i; }
   ...> Complex add(Complex x) { return new Complex(r+x.r, i+x.i); }
   ...> Complex multi(Complex x) { return new Complex(r*x.r - i*x.i, r*x.i + i*x.r); }
   ...> public String toString() { return r + "+" + i + "i"; }
   ...> }
|  次を作成しました: クラス Complex

jshell>

 複素数は実数部と虚数部を持つ数です。Complexクラスでは実数をフィールドr、虚数をフィールドiで表しています。このクラスはJShell内だけで使用するので、デフォルトのスコープで定義しています。

 toStringメソッドだけは、ObjectクラスのtoStringクラスをオーバーライドしているので、publicで定義しました。

 さて、定義はできたので、Complexクラスを使用してみましょう。

jshell> Complex x = new Complex(1, 2)
x ==> 1.0+2.0i

jshell> Complex y = new Complex(2, 2)
y ==> 2.0+2.0i

jshell> Complex s = x.add(y)
s ==> 3.0+4.0i

jshell> Complex t = x.multi(y)
t ==> -2.0+6.0i

jshell>

 JShellで定義したクラスでも、普通のクラスのように使用できました。