简体   繁体   English

在 JShell 中,如何评估整个 java 代码?

[英]In JShell, How to evaluate whole java code?

I'm using the JShell API to run Java code.我正在使用 JShell API 来运行 Java 代码。 However, I got an error when I run a whole code.但是,当我运行整个代码时出现错误。

For example:例如:

import jdk.jshell.JShell;

var code= """
          void hello(){
              System.out.println("Hello world");
          }
                                        
          hello();
          """;

JShell shell = JShell.create();
List<SnippetEvent> snippets = shell.eval(code);

After evaluation, I see the error in output snippet.评估后,我在 output 片段中看到错误。

cannot find symbol
  symbol:   method hello()
  location: class 

What is the problem here?这里有什么问题?

eval is not designed to handle code like that. eval不是为处理这样的代码而设计的。 The code you showed is actually 2 "complete snippets" that needs to be broken up before you pass into eval .您显示的代码实际上是 2 个“完整片段”,在您进入eval之前需要将其分解。 From the docs :文档

The input should be exactly one complete snippet of source code, that is, one expression, statement, variable declaration, method declaration, class declaration, or import.输入应该是完整的源代码片段,即一个表达式、语句、变量声明、方法声明、class 声明或导入。 To break arbitrary input into individual complete snippets, use SourceCodeAnalysis.analyzeCompletion(String) .要将任意输入分解为单独的完整片段,请使用SourceCodeAnalysis.analyzeCompletion(String)

The "real" JShell command line program probably uses the SourceCodeAnalysis.analyzeCompletion(String) method to break up your input into two complete snippets, and passes each of them into eval . “真正的”JShell 命令行程序可能使用SourceCodeAnalysis.analyzeCompletion(String)方法将您的输入分解为两个完整的片段,并将每个片段传递给eval

Here is how to use SourceCodeAnalysis.analyzeCompletion(String) :以下是如何使用SourceCodeAnalysis.analyzeCompletion(String)

var code = "...";
JShell jshell = JShell.create();
SourceCodeAnalysis.CompletionInfo completionInfo = jshell.sourceCodeAnalysis().analyzeCompletion(code);

// this is the shortest complete code
System.out.println(completionInfo.source());

// this is what remains after removing the shortest complete code
// you'd probably want to analyze the completion of this recursively
System.out.println(completionInfo.remaining());

hello(); fails to compile for the same reason that由于同样的原因无法编译

class Foo {
    void hello() {

    }

    hello();
}

doesn't compile.不编译。

If you look at the diagnostics:如果您查看诊断:

JShell shell = JShell.create();
List<SnippetEvent> events = shell.eval(code);
shell.diagnostics(events.get(0).snippet()).forEach(x -> System.out.println(x.getMessage(Locale.ENGLISH)));

You get:你得到:

Invalid method declaration;无效的方法声明; return type required需要返回类型

That is the exact error message you get if you put a method call at class level.如果您将方法调用置于 class 级别,这就是您收到的确切错误消息。

Anyway, to make your code work, simply eval the method declaration first, then eval the hello();无论如何,要使您的代码正常工作,只需先eval方法声明,然后eval hello(); call.称呼。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM