パッケージ jdk.jshell
JShellは中央クラスです。 JShellのインスタンスは、ソース・スニペットの現在のセットとそれらが生成した実行状態の両方である評価状態を保持します。
各ソース・スニペットは、Snippetのサブクラスのインスタンスで表されます。 たとえば、文はStatementSnippetのインスタンスによって表され、メソッド宣言はMethodSnippetのインスタンスによって表されます。 スニペットは、1つ以上のコード・スニペットを含む入力でJShell.eval(String)が呼び出されたときに作成されます。
スニペットのコンパイル・ステータスに対する変更は、SnippetEventで報告されます。 スニペットのステータスには、evalを使用して作成し、JShell.drop(jdk.jshell.Snippet)を使用してアクティブなソース状態から削除し、別のスニペットのステータス変更の結果としてステータスを更新できるという3つの大きな変更があります。 たとえば、jsを指定すると、JShellのインスタンスでjs.eval("int x = 5;")を実行すると、変数xがソース状態に追加され、xのVarSnippetの作成を示すイベントが生成されます。 その後、js.eval("int timesx(int val) { return val * x; }")を実行すると、ソース状態にメソッドが追加され、timesxのMethodSnippetの作成を示すイベントが生成されます。 varxがevalへの最初のコールによって作成されたスニペットを保持し、js.drop(varx)を実行すると2つのイベントが生成されるとします。1つは変数スニペットのステータスをDROPPEDに変更するためのイベントで、もう1つはメソッド・スニペットを更新するためのイベントです(現在はxへの未解決の参照があります)。
もちろん、APIの一般的なアプリケーションの場合、入力は固定文字列ではなく、ユーザーからのものになります。 次に、APIを使用してREPLを実装する方法の非常に簡略化された例を示します。
import java.io.ByteArrayInputStream;
import java.io.Console;
import java.util.List;
import jdk.jshell.*;
import jdk.jshell.Snippet.Status;
class ExampleJShell {
public static void main(String[] args) {
Console console = System.console();
try (JShell js = JShell.create()) {
do {
System.out.print("Enter some Java code: ");
String input = console.readLine();
if (input == null) {
break;
}
List<SnippetEvent> events = js.eval(input);
for (SnippetEvent e : events) {
StringBuilder sb = new StringBuilder();
if (e.causeSnippet == null) {
// We have a snippet creation event
switch (e.status) {
case VALID:
sb.append("Successful ");
break;
case RECOVERABLE_DEFINED:
sb.append("With unresolved references ");
break;
case RECOVERABLE_NOT_DEFINED:
sb.append("Possibly reparable, failed ");
break;
case REJECTED:
sb.append("Failed ");
break;
}
if (e.previousStatus == Status.NONEXISTENT) {
sb.append("addition");
} else {
sb.append("modification");
}
sb.append(" of ");
sb.append(e.snippet.source());
System.out.println(sb);
if (e.value != null) {
System.out.printf("Value is: %s\n", e.value);
}
System.out.flush();
}
}
} while (true);
}
System.out.println("\nGoodbye");
}
}
ステータス変更イベントに登録するには、JShell.onSnippetEvent(java.util.function.Consumer)を使用します。 これらのイベントは、evalおよびdropによってのみ生成され、これらのメソッドの戻り値は、そのコールによって生成されるイベントのリストです。 したがって、前述の例のように、イベントを登録せずにイベントを使用できます。
この例を試してみると、セミコロンを使用して文または変数宣言を終了しないと、単に失敗することになります。 未完了のエントリ(必要な複数行メソッドなど)も、1行の後に失敗します。 SourceCodeAnalysis内のユーティリティーは、このようなケースに対処するためのソース境界および完全性分析を提供します。 SourceCodeAnalysisは、タブ補完で使用される場合と同様に、入力の推奨完了も提供します。
- 導入されたバージョン:
- 9
-
インタフェースのサマリー インタフェース 説明 SourceCodeAnalysis.CompletionInfo analyzeCompletion(String input)の結果。SourceCodeAnalysis.Documentation 指定されたユーザーの入力を継続するための候補のドキュメント。SourceCodeAnalysis.SnippetWrapper Javaソースのスニペットを有効な最上位Javaソースにラップする。SourceCodeAnalysis.Suggestion 指定されたユーザーの入力を継続するための候補。 -
クラスのサマリー クラス 説明 DeclarationSnippet すべての宣言スニペットのグループ化: 変数宣言(VarSnippet)、メソッド宣言(MethodSnippet)および型宣言(TypeDeclSnippet)Diag スニペットの診断情報。ErroneousSnippet 有効なJavaプログラミング言語コードではないコードのスニペット。ExpressionSnippet 代入式または変数値式のスニペット。ImportSnippet インポート宣言のスニペット。JShell JShell評価状態エンジン。JShell.Builder JShellインスタンス用のビルダー。MethodSnippet メソッド定義のスニペット。PersistentSnippet 将来のコードを保持および影響するスニペットのグループ化。Snippet スニペットは、JShell.eval(java.lang.String)に渡されるJavaソース・コードのスニペットを表します。SnippetEvent スニペットに対する変更の説明。SourceCodeAnalysis ソース・コード入力用の分析ユーティリティを提供します。SourceCodeAnalysis.QualifiedNames 使用可能な修飾名のリスト。StatementSnippet 文のスニペット。TypeDeclSnippet 型定義のスニペット(クラス、インタフェース、enumまたは注釈インタフェース定義)。VarSnippet 変数定義のスニペット。 -
列挙型のサマリー 列挙型 説明 Snippet.Kind 一般的なスニペットについて説明します。Snippet.Status スニペットの現在の状態を示します。Snippet.SubKind スニペットの詳細な種類。SourceCodeAnalysis.Completeness 指定された入力の完全性を示します。 -
例外のサマリー 例外 説明 EvalException 実行中のクライアント内でスローされるスロー可能オブジェクトをラップします。JShellException JShellで生成された例外のスーパークラスUnresolvedReferenceException RECOVERABLE_DEFINEDスニペットを実行しようとしたときに報告された例外。