JavaOne 2016キーノートの間、Mark Reinhold氏は、氏はJavaプラットフォームグループのチーフアーキテクトだが、 Java 9はそこをターゲットにした85のJEPにおいて見られるように、Jigsawより大きくなることを指摘した。私は彼が強調した新しいJavaの機能を議論したいと思う。JEP 222であるJava shellだ(JShellとしても知られている)。
JShellとともに、Java 9は開発者がRead-Eval-Print loop(REPL)を使えるようにする。これはユーザの入力を評価し値や状態変化として出力するインタラクティブなツールだ。
JShellとは何か?
JShellはコードスニペットの評価を助けるAPIとツールである。スニペットはJava言語仕様(JLS)の構文定義と一致しなければならない。JShellはまたクエリとコマンドを評価する。スラッシュから始めることでコマンドはスニペットと区別される。サンプルは以下のようなものだ。
jshell> /import
| import java.util.*
| import java.io.*
| import java.math.*
| import java.net.*
| import java.util.concurrent.*
| import java.util.prefs.*
| import java.util.regex.*
JShellの状態はJVMインスタンスの後にモデル化される。JShellはコード分析とタブ補完、その他の間にある未処理のスニペットのパースのためにコンパイラAPIを利用している。コード置換のためにJava Debug Interface (JDI)を使っている。
ユーザはまた、インタラクティブなインタフェースを回避したいときはバッチスクリプトを使うこともできる。
JavaOneでのJShellデモ
JavaOneでのReinholdがプレゼンテーションしたデモに行く前に、私は次のことに言及したい。もしJava 9 JDKの最新バージョンがあり、java –version
とタイプしたとき、出力されたバージョン文字列についての変化に気づくだろう。次にようになるはずだ。
$ java -version
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+136)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+136, mixed mode)
対象的にこれは古いフォーマットだ。
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
変化はJEP 223で新しく導入されたスキーマによるものだ。このバージョン文字列は今やより解析可能であり、またセマンティックなバージョニングを強調するものとして現在の業界のプラクティスを含めて、よりインラインとなっている。新しいスキーマはメジャー、マイナー、もしくはセキュリティアップデートを簡単に識別する手助けをしてくれる。
上記のサンプルにおいて、プレリリース識別子(ea
、これは“early access”と読む)は先に“-”がつき、それから“+”が続き、実行したビルド番号(136
)がつく。
デモに戻ると、もしコマンドラインで“jshell
“とタイプすれば、JShellプロンプトが表示されるだろう。次のようになる。
$ jshell
| Welcome to JShell -- Version 9-ea
| For an introduction type: /help intro
jshell>
もし次のような単純な文字列宣言をタイプすれば、呼び出し可能なメソッドを調べることができるだろう(オーバーロードされたメソッドを含む)。
jshell> String x = "foo bar baz"
x ==> "foo bar baz"
jshell> x.
charAt( chars() codePointAt(
codePointBefore( codePointCount( codePoints()
compareTo( compareToIgnoreCase( concat(
contains( contentEquals( endsWith(
equals( equalsIgnoreCase( getBytes(
getChars( getClass() hashCode()
indexOf( intern() isEmpty()
lastIndexOf( length() matches(
notify() notifyAll() offsetByCodePoints(
regionMatches( replace( replaceAll(
replaceFirst( split( startsWith(
subSequence( substring( toCharArray()
toLowerCase( toString() toUpperCase(
trim() wait(
jshell> x.substring(4,7)
$3 ==> "bar"
jshell> Arrays.asList(x.split(""))
$5 ==> [f, o, o, , b, a, r, , b, a, z]
jshell> Arrays.asList(x.split(" "))
$6 ==> [foo, bar, baz]
上記のサンプルでは、必要となるさらなる式を評価するために使うかもしれない、いくつかの仮の変数を示している($3, $5, $6)。
jshell> import java.util.stream.*
jshell> $6.stream().filter(s -> s.startsWith("b")).collect(Collectors.toList())
$9 ==> [bar, baz]
上記のサンプルではjava.util.stream
パッケージをインポートしている。Collectorsクラスのメソッドリストを取得しタブ補完できるようにするためだ。
結論
JShellはJava REPLを連れてきた。定評のあるLISPマシンのとても役に立つ機能だ。開発者が全体をコンパイルして実行とデバッグをすることなくコードスニペットをデバッグできるようにする手助けをする。
Rate this Article
- Editor Review
- Chief Editor Action