如何运行在JShell中作为片段添加的整个Java文件? [英] How to run a whole Java file added as a snippet in JShell?

查看:105
本文介绍了如何运行在JShell中作为片段添加的整个Java文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试安装JDK 9 Early Access版本172来与JShell一起玩. 当我尝试打开一个简单的Java文件并在将其添加为代码段后执行它时,它只是显示了修改后的类Test并增加了代码段数.您能帮我弄清楚我出了什么问题吗?

I tried installing JDK 9 Early access version 172 to play around with JShell. When I tried to open a simple java file and execute it after adding it as a snippet, it just showed modified class Test and increased the snippet number. Can you please help me realize where I went wrong?

|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro

jshell> /open G:\kavitha\Test.java

jshell> /list

   1 : public class Test{
        public static void main(String[] args){
                 int i = 1;
                 int j = 2;
             System.out.println("Sum of 1 and 2 is : " + (i+j));
        }
       }

jshell> /1
public class Test{
        public static void main(String[] args){
                 int i = 1;
                 int j = 2;
             System.out.println("Sum of 1 and 2 is : " + (i+j));
        }
}
|  modified class Test

jshell> /list

   2 : public class Test{
        public static void main(String[] args){
                 int i = 1;
                 int j = 2;
             System.out.println("Sum of 1 and 2 is : " + (i+j));
        }
       }

推荐答案

/open仅加载文件,此后您必须告诉jshell您要执行的操作.

/open only loads the file, after that you have to tell jshell what you want to execute.

示例:

jshell> /open Test.java

jshell> /list

   1 : class Test {
           public static void main(String[] args) {
               System.out.println("Hello Kavitha");
           }
           int rollDice() {
               return 1 + (int)(6 * Math.random());
           }
       }

jshell> Test.main(new String[0])
Hello Kavitha

jshell> new Test().rollDice()
$3 ==> 3

这里我已经执行了main方法,但是我也可以根据需要使用已加载的类,创建新实例,调用方法等.

Here I have executed main method, but I can also use the loaded class as I want, create a new instance, invoke a method, etc.

快捷方式/<id>使用该ID重新运行代码段.在您的情况下,代码段1仅加载该类并且不执行任何操作,因此通过执行/1您可以重新加载相同的类,而无需执行它.

Shortcut /<id> re-runs snippet with that id. In your case, snippet 1 only loads the class and executes nothing, so by executing /1 you re-loaded the same class, again without executing it.

运行上面的示例后,/2将重新运行main方法,而/3将重新滚动骰子:

After running my example above, /2 would re-run the main method, and /3 would re-roll the dice:

jshell> /3
new Test().rollDice()
$4 ==> 1

jshell> /3
new Test().rollDice()
$5 ==> 6

jshell> /3
new Test().rollDice()
$6 ==> 2


附录:/open&编译,类加载,类初始化

(试图弄清为什么为什么 /open没有执行您的类的main方法,并证明它是有道理的)


Addendum: /open & compilation, class loading, class initialization

(Trying to clarify why /open did not execute the main method of your class, and to show that it makes sense)

当您/open文件时,JShell会添加文件的内容,就像您在外壳中键入文件一样.

When you /open a file, JShell will add the content of the file as if you typed it into the shell.

然后它将编译代码段,但不会 初始化 类(如果有).

It will then compile the snippet(s), but it will not initialize classes if there were any.

(我不确定是否加载类,这是初始化之前的步骤,很难说清,请参见

(I'm not sure whether or not if will load classes, which is the step before initialization, it's difficult to tell, see this post that was an attempt to explore the internals of JShell, it shows how class names in JShell are translated for the user, and failed attempts to see the list of loaded classes -- but that matters less than compilation & initialization)

如果我打开包含以下内容的SnippetWithError.txt:

If I open SnippetWithError.txt which contains the following:

System.out.println("Hey")
class Foo { int n=33; } bar

(是的,它不必是Java文件,实际上是一堆包含在外壳中以供评估的文本)

(yes it does not need to be a java file, it's really a bunch of text you include in the shell for evaluation)

jshell> /open SnippetWithError.txt
Hey
|  Error:
|  cannot find symbol
|    symbol:   variable bar
|   bar
|   ^-^

看到它印有嘿"字样,并且包含了类Foo:

See it printed "Hey", and it has included class Foo:

jshell> new Foo().n
$2 ==> 33

因此,当您/open时,JShell 编译会执行这些语句,但是如果某些语句是类或方法声明,则它不会执行那些声明,甚至不会 initialize 类.

So, JShell compiles when you /open, it executes the statements, but if some statements are class or method declarations, it does not execute those, it does not even initialize the classes.

请参阅下文,将导入方式在历史记录中如何计为单独的语句,然后将类声明放在其自己的语句中(#3):

See below how the imports are counted as separate statements in the history, then the class declaration is in its own statement (#3):

jshell> /open HasStaticInitBlock.java

jshell> /list

1 : import java.time.Duration;
2 : import java.time.Instant;
3 : class HasStaticInitBlock {
        static Instant t0 = Instant.now();
        static {
            System.out.println("Class initialized at " + t0);
        }
        static Duration timeSinceInit() {
            return Duration.between(t0, Instant.now());
        }
    }

jshell> HasStaticInitBlock.timeSinceInit()
Class initialized at 2017-06-07T06:49:06.746185Z
$4 ==> PT0.040414S

jshell> HasStaticInitBlock.timeSinceInit()
$5 ==> PT2.343019S

仅在需要时执行类初始化.

Class initialization was only performed when needed.

这篇关于如何运行在JShell中作为片段添加的整个Java文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆