Module  jdk.jshell

Package jdk.jshell

提供用于创建工具的界面,例如阅读评估打印循环(REPL),它交互地评估Java编程语言代码的“片断”。 “片段”是单个表达式,语句或声明。 此功能可用于增强IDE等工具,也可以独立使用。

JShell是中央阶级。 JShell的实例具有评估状态,它既是当前的源代码片段以及它们所生成的执行状态。

每个源代码段由Snippet的子类的实例表示。 例如,语句由StatementSnippet的实例表示 ,方法声明由MethodSnippet的实例表示 当使用包含一个或多个代码段的输入调用JShell.eval(String)时,将创建代码段。

使用SnippetEvent报告对代码段的编译状态的任何更改。 对代码段的状态有三种主要的更改:可以使用eval创建,它可以通过eval从活动源状态删除 ,并且可以通过另一个代码段的状态更改来更新其状态。 例如:给定js ,的一个实例JShell ,执行js.eval("int x = 5;")将所述变量添加x到源状态和将生成描述的创建的事件VarSnippetx 然后执行js.eval("int timesx(int val) { return val * x; }")将向源状态添加一个方法,并将生成一个描述为timesx创建MethodSnippettimesx 假设varx保存由第一次调用eval创建的片段,执行js.drop(varx)将生成两个事件:一个用于将变量代码段的状态更改为DROPPED ,另一个用于更新方法代码段(现在有一个未解析的引用到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) 这些事件仅由evaldrop生成,这些方法的返回值是该调用生成的事件的列表。 因此,如上例所示,可以使用事件而不注册接收事件。

如果您尝试使用此示例,您将看到无法使用分号终止语句或变量声明将会失败。 未完成的条目(例如所需的多行方法)也将在一行之后失败。 SourceCodeAnalysis的实用程序提供源边界和完整性分析,以解决这些情况。 SourceCodeAnalysis还提供了建议的输入完成,可以在tab-completion中使用。

从以下版本开始:
9