Package jdk.jshell
JShell
是中心类。一个JShell
实例保存了评估状态,即当前的源代码片段集合和它们产生的执行状态。
每个源代码片段由Snippet
的子类实例表示。例如,语句由StatementSnippet
的实例表示,方法声明由MethodSnippet
的实例表示。当使用包含一个或多个代码片段的输入调用JShell.eval(String)
时,将创建片段。
有关片段编译状态的任何更改都将使用SnippetEvent
报告。片段状态的更改有三种主要类型:使用eval
创建,使用JShell.drop(jdk.jshell.Snippet)
从活动源状态中删除,以及由于另一个片段的状态更改而更新其状态。例如:给定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)
将生成两个事件:一个用于将变量片段的状态更改为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)
。这些事件仅由eval
和drop
生成,这些方法的返回值是该调用生成的事件列表。因此,就像上面的示例一样,可以在不注册接收事件的情况下使用事件。
如果您尝试此示例,您将看到未能使用分号终止语句或变量声明将导致失败。未完成的条目(例如期望的多行方法)也将在一行后失败。在这种情况下,SourceCodeAnalysis
中的实用程序提供源边界和完整性分析,以解决这类情况。 SourceCodeAnalysis
还提供了输入的建议完成,就像在制表完成中使用的那样。
- 自版本:
- 9
-
ClassDescription用于片段的诊断信息。无效的Java编程语言代码片段。包装在执行客户端中抛出的可抛出异常。用于赋值或变量值表达式的片段。用于导入声明的片段。JShell评估状态引擎。
JShell
实例的构建器。为用户片段中的Console
提供功能的接口。JShell生成异常的超类方法定义的片段。持久存在并影响未来代码的片段分组。片段表示传递给JShell.eval(java.lang.String)
的Java源代码片段。描述片段的一般类型。描述片段的当前状态。片段的详细种类。对片段的更改的描述。为源代码输入提供分析实用程序。可用于推导着色的跨度属性。描述给定输入的完整性。analyzeCompletion(String input)
的结果。给定用户输入的继续候选的文档。为片段内的跨度分配可用于着色的属性。可能的限定名称列表。将Java源代码片段包装为有效的顶级Java源代码。给定用户输入的继续候选。语句的片段。类型定义的片段(类、接口、枚举或注解接口定义)。尝试执行RECOVERABLE_DEFINED
片段时报告的异常。变量定义的片段。