如何将 运行 整个 Java 文件作为片段添加到 JShell 中?
How to run a whole Java file added as a snippet in JShell?
我尝试安装 JDK 9 抢先体验版 172 以使用 JShell。
当我尝试打开一个简单的 java 文件并在将其添加为代码段后执行它时,它只显示修改后的 class 测试并增加了代码段编号。你能帮我看看我错在哪里吗?
| 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你想执行什么。
示例:
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
这里我执行了main
方法,但我也可以根据需要使用加载的class,创建新实例,调用方法等
快捷方式 /<id>
重新 运行 具有该 ID 的代码段。在你的例子中,片段 1 只加载 class 并且什么都不执行,所以通过执行 /1
你重新加载了相同的 class,再次没有执行它。
在运行我上面的例子之后,/2
会重新运行主要方法,/3
会重新掷骰子:
jshell> /3
new Test().rollDice()
==> 1
jshell> /3
new Test().rollDice()
==> 6
jshell> /3
new Test().rollDice()
==> 2
附录:/open
& 编译,class 加载,class 初始化
(试图弄清楚为什么 /open
没有执行你的class的main方法,并证明它是有道理的)
当您 /open
一个文件时,JShell 将添加文件的内容 就好像您将它输入到 shell.
然后它将 编译 片段,但它不会 initialize class 如果有的话。
(不知道if会不会load classes,这是初始化前的步骤,不好说,见this post 那是一次探索 JShell 内部结构的尝试,它显示了 JShell 中的 class 名称是如何为用户翻译的,并且尝试查看加载的 classes 列表失败了——但这很重要少于编译和初始化)
如果我打开 SnippetWithError.txt
其中包含以下内容:
System.out.println("Hey")
class Foo { int n=33; } bar
(是的,它不需要是 java 文件,它实际上是您包含在 shell 中用于评估的一堆文本)
jshell> /open SnippetWithError.txt
Hey
| Error:
| cannot find symbol
| symbol: variable bar
| bar
| ^-^
看到它打印出来 "Hey",它包含了 class Foo
:
jshell> new Foo().n
==> 33
所以,当你/open
时,JShell 编译,它会执行语句,但如果某些语句是class或方法声明,它不会执行那些,它甚至不 初始化 classes.
请参阅下面如何将导入计算为历史记录中的单独语句,然后 class 声明在其自己的语句中(#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
==> PT0.040414S
jshell> HasStaticInitBlock.timeSinceInit()
==> PT2.343019S
Class 只在需要时才进行初始化。
我尝试安装 JDK 9 抢先体验版 172 以使用 JShell。 当我尝试打开一个简单的 java 文件并在将其添加为代码段后执行它时,它只显示修改后的 class 测试并增加了代码段编号。你能帮我看看我错在哪里吗?
| 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你想执行什么。
示例:
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
这里我执行了main
方法,但我也可以根据需要使用加载的class,创建新实例,调用方法等
快捷方式 /<id>
重新 运行 具有该 ID 的代码段。在你的例子中,片段 1 只加载 class 并且什么都不执行,所以通过执行 /1
你重新加载了相同的 class,再次没有执行它。
在运行我上面的例子之后,/2
会重新运行主要方法,/3
会重新掷骰子:
jshell> /3
new Test().rollDice()
==> 1
jshell> /3
new Test().rollDice()
==> 6
jshell> /3
new Test().rollDice()
==> 2
附录:/open
& 编译,class 加载,class 初始化
(试图弄清楚为什么 /open
没有执行你的class的main方法,并证明它是有道理的)
当您 /open
一个文件时,JShell 将添加文件的内容 就好像您将它输入到 shell.
然后它将 编译 片段,但它不会 initialize class 如果有的话。
(不知道if会不会load classes,这是初始化前的步骤,不好说,见this post 那是一次探索 JShell 内部结构的尝试,它显示了 JShell 中的 class 名称是如何为用户翻译的,并且尝试查看加载的 classes 列表失败了——但这很重要少于编译和初始化)
如果我打开 SnippetWithError.txt
其中包含以下内容:
System.out.println("Hey")
class Foo { int n=33; } bar
(是的,它不需要是 java 文件,它实际上是您包含在 shell 中用于评估的一堆文本)
jshell> /open SnippetWithError.txt
Hey
| Error:
| cannot find symbol
| symbol: variable bar
| bar
| ^-^
看到它打印出来 "Hey",它包含了 class Foo
:
jshell> new Foo().n
==> 33
所以,当你/open
时,JShell 编译,它会执行语句,但如果某些语句是class或方法声明,它不会执行那些,它甚至不 初始化 classes.
请参阅下面如何将导入计算为历史记录中的单独语句,然后 class 声明在其自己的语句中(#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
==> PT0.040414S
jshell> HasStaticInitBlock.timeSinceInit()
==> PT2.343019S
Class 只在需要时才进行初始化。