Package jdk.jshell
JShell
是中央阶级。 JShell
的实例具有评估状态,它既是当前的源代码片段以及它们所生成的执行状态。
每个源代码段由Snippet
的子类的实例表示。 例如,语句由StatementSnippet
的实例表示 ,方法声明由MethodSnippet
的实例表示 。 当使用包含一个或多个代码段的输入调用JShell.eval(String)
时,将创建代码段。
使用SnippetEvent
报告对代码段的编译状态的任何更改。 对代码段的状态有三种主要的更改:可以使用eval
创建,它可以通过eval
从活动源状态删除 ,并且可以通过另一个代码段的状态更改来更新其状态。 例如:给定js
,的一个实例JShell
,执行js.eval("int x = 5;")
将所述变量添加x
到源状态和将生成描述的创建的事件VarSnippet
为x
。 然后执行js.eval("int timesx(int val) { return val * x; }")
将向源状态添加一个方法,并将生成一个描述为timesx
创建MethodSnippet
的timesx
。 假设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
还提供了建议的输入完成,可以在tab-completion中使用。
- 从以下版本开始:
- 9
-
接口摘要 接口 描述 SourceCodeAnalysis.CompletionInfo 结果为analyzeCompletion(String input)
。SourceCodeAnalysis.Documentation 用于继续给定用户输入的候选人的文档。SourceCodeAnalysis.SnippetWrapper 将Java源代码片段包装到有效的顶级Java源代码中。SourceCodeAnalysis.Suggestion 用于继续给定用户输入的候选者。 -
类摘要 Class 描述 DeclarationSnippet 分组所有声明片段:变量声明(VarSnippet
),方法声明(MethodSnippet
)和类型声明(TypeDeclSnippet
)。Diag 代码段的诊断信息。ErroneousSnippet 一段代码无效的Java编程语言代码。ExpressionSnippet 赋值或变量值表达式的代码段。ImportSnippet 导入声明的代码段。JShell JShell评估状态引擎。JShell.Builder Builder为JShell
实例。MethodSnippet 方法定义的代码段。PersistentSnippet 对持续存在并影响未来代码的片段进行分组。Snippet 代码片段代表传递给JShell.eval
的Java源代码片段。SnippetEvent 对代码段的更改的描述。SourceCodeAnalysis 提供源代码输入的分析实用程序。SourceCodeAnalysis.QualifiedNames 可能的合格名称列表。StatementSnippet 一段语句的片段TypeDeclSnippet 类型定义的代码段(类,接口,枚举或注释接口定义)。VarSnippet 变量定义的代码段。 -
枚举摘要 Enum 描述 Snippet.Kind 描述一般的片段。Snippet.Status 描述代码段的当前状态。Snippet.SubKind 一个片段的详细种类。SourceCodeAnalysis.Completeness 描述给定输入的完整性。 -
异常摘要 异常 描述 EvalException 封装在远程执行客户机中抛出的异常。JShellException JShell的超类生成异常UnresolvedReferenceException 在尝试执行RECOVERABLE_DEFINED
代码段时报告异常。