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