模块  jdk.jshell

Package jdk.jshell

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

JShell是中央阶级。 JShell的实例保存评估状态,该状态既是当前的源代码段集,也是它们生成的执行状态。

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

使用SnippetEvent报告对代码段编译状态的任何更改。 代码段状态有三种主要的更改:它可以使用eval创建,可以使用eval从活动源状态中删除 ,并且可以通过另一个代码段中的状态更改来更新其状态。 例如:给定js ,执行js.eval("int x = 5;")的实例为JShell ,将变量x添加到源状态,并将生成描述5238455446989x的创建事件。 然后执行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还提供了输入的建议完成,可以在制表符完成中使用。

从以下版本开始:
9