包 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
-
类描述片段的诊断信息。一段代码不是有效的 Java 编程语言代码。包装在执行客户端中抛出的可抛出对象。赋值或变量值表达式的片段。进口申报的片段。JShell 评估状态引擎。
JShell
个实例的生成器。JShell 的超类产生异常方法定义的片段。对持续存在并影响未来代码的片段进行分组。片段表示传递给JShell.eval(java.lang.String)
的 Java 源代码片段。描述一般类型的片段。描述片段的当前状态。片段的详细种类。对代码段更改的描述。为源代码输入提供分析实用程序。可用于派生着色的 span 属性。描述给定输入的完整性。analyzeCompletion(String input)
的结果。继续给定用户输入的候选人的文档。将可用于着色的属性分配给片段内的跨度。可能的限定名称列表。将一段 Java 源代码包装到有效的顶级 Java 源代码中。继续给定用户输入的候选者。声明的片段。类型定义(类、接口、枚举或注解定义)的片段。尝试执行RECOVERABLE_DEFINED
片段时报告异常。变量定义的片段。