您现在的位置是:首页 > 文章详情

关于 JDK 9 中的 JShell,你应该了解的 10 件事

日期:2019-04-06点击:270

JShell 是在 JDK 9 中首次引入的,以 Kulla 实现的 Java Enhancement Proposal (JEP) 222 规范的一部分。很多编程语言如 JavaScript、Python、Ruby 等,提供了非常易用的命令行执行工具,但 Java 一直缺失此功能。因此 JDK 9 引入了 Java shell 工具 —— JShell。

在之前的 文章 中我们曾经讨论了 JShell 的一些基础知识,这篇文字中我们主要聊一些高级的概念。

1. 变量重新定义

在 Java 中,我们是没法对一个变量进行重新声明的。但是有了 JShell,我们可以随时在需要的时候对一个变量重新进行定义,包括原生类型以及引用类型变量。

示例:

jshell> String str="Hello" str ==> "JShell"
jshell> Integer str=10 str ==> 10

2. 临时变量 (Scratch Variables)

在 JShell 命令行中可以将任意表达式计算的结果赋值给变量,尽管你并没有显式的赋值。这样的变量称为临时变量。例如:

jshell> "Hello"+"JShell" $1 ==> "HelloJShell"

请注意为了让 JShell 知道变量类型以及表达式计算的详细信息,我们可以设置 feeback 为详细模式:

/set feedback verbose
jshell> 60+10 $2 ==> 70 | created scratch variable $21 : int

要退出详细模式,只需转回正常模式即可:

/set feedback normal

3. JShell 的前向引用 ( Forward referencing )

JShell 的前向引用 (Forward referencing) 可以让你在未定义某些方法时仍然可以调用。例如,假设我们有一个名为 greet() 的方法(如下所示)。而 greet() 内部调用了另外一个尚未定义 greetHelloWorld() 方法,这种情况下我们仍可以正确的创建 greet() 方法,但只有在 greetHelloWorld 方法创建后才可以被调用。这就是 JShell 的前向引用。

示例:

jshell> public void greet(){ ...> greetHelloWorld();} | created method greet(), however, it cannot be invoked until method greetHelloWorld() is declared              jshell> greet() | attempted to call method greet() which cannot be invoked until method greetHelloWorld() is declared
jshell> public void greetHelloWorld(){ ...> System.out.println("Hello World");} | created method greetHelloWorld()
jshell> greet() Hello World

4. JShell 的异常处理

示例:

jshell> int divide(int a,int b) throws IOException{ ...> if(b==0){ ...> throw new IOException(); ...> } ...> return a/b; ...> } | created method divide(int,int)
jshell> divide(1,0) | java.io.IOException thrown: | at divide (#2:3) | at (#3:1)

注意这里我们并没有捕获任何关于 divide 方法的异常,但是 JShell 会帮我们处理好。同时这里我们也没有引入 IOException 类,但代码的编译和执行都没有任何问题。原因是 JShell 的整个会话过程中会自动的引入一些常用的包,你可以使用 /imports 命令来查看 JShell 默认引用的包:

jshell> /imports | import java.io.* | import java.math.* | import java.net.* | import java.nio.file.* | import java.util.* | import java.util.concurrent.* | import java.util.function.* | import java.util.prefs.* | import java.util.regex.* | import java.util.stream.* | import java.io.IOException

5. JShell 会话的指令持久化行为

默认情况下 JShell 会话中的所有指令都是不被持久化的,这些指令是易失的,当用户退出 JShell 会话时就会丢失。

但是 JShell 提供了在特定的会话中保存所有指令信息的方法,你可以在另外一个新的会话中使用这些指令。当用户需要保存一些有用的代码片段时候,这个功能是很好用的。

示例:

 

jshell> String s="Hello" s ==> "Hello" jshell> int i=100; i ==> 100
jshell> /save C:\data\mySession.jsh
jshell> /exit | Goodbye λ jshell | Welcome to JShell -- Version 9.0.4 | For an introduction type: /help intro
jshell> /vars
jshell> /open C:\Data\mySession.jsh
jshell> /vars | String s = "Hello" | int i = 100

6. 使用外部库

有很多的第三方开源库,一般开发者需要将这些库放到项目的类路径才可以使用。但是在 JShell 中,使用这些三方库更简单。

例如我们想使用 Apache Commons Lang 中的字符串工具包,可以使用如下语法来使用第三方库包:

(译者注:其实并没有那么方便)

shell> /env --class-path <Relative Path of lib from where JShell is run>
jshell> /env --class-path ../lib/commons-lang3-3.8.1.jar | Setting new options and restoring state.
import org.apache.commons.lang3.StringUtils;
jshell> System.out.println(StringUtils.isEmpty("")) true
jshell> System.out.println(StringUtils.isEmpty("hello")) false

7. 使用专门的 JShell 命令和工具来加速开发

JShell 包含很多很有用的命令,这些方法可以加速代码的测试,例如:

 /history - Prints all commands executed on JShell (Java Commands+ JShell specific commands)

示例:

jshell> String s ="Hello" s ==> "Hello" jshell> class Employee{ ...> } | created class Employee jshell> /vars | String s = "Hello" jshell> /history String s ="Hello" class Employee{ } /vars /history
 /list    - Prints all JAVA related commands executed in JShell. Notice that this list the command in Numerical              order of each command identifier. This identifier can be used to execute certain construct again.

示例:

jshell> /list 1 : String s ="Hello"; 2 : class Employee{ }
jshell> /1 String s ="Hello"; s ==> "Hello"
/reset   - Resets the state of current JShell session.
CTRL+R   - For searching a particular command
CTRL+S   - Performing Forward Search
CTRL+C   - To exit from JShell session
/exit    - To exit from JShell session
/vars     - To list all variables inside current JShell session
/imports  - To list all imports inside current JShell session
/help    - To know more about JShell specific commands

8. JShell 使用 Tab 键自动完成

JShell 可以使用 Tab 键来达到代码自动完成的功能。

示例:

除了这些,你还可以在 JShell 中查看相关包的文档:

jshell> java.io io Signatures: java.io
<press tab again to see documentation>

9. 编辑已执行命令

在开发过程中我们经常会需要修改之前执行的命令,JShell 可以很方便的实现。

示例:

/edit        - Edit all constructs in current JShell session
/edit 1      - Edit only 1st construct (see from /list) in current JShell session
/edit Person - Edit only Person class in current JShell session

10. 如何对 JShell 扩展编程

JDK 提供 API 用来访问 JShell ,这些 API 可以浏览 JavaDoc 了解详情。

这篇文字里我们介绍了一些 JShell 的高级特性,但这并非全部,建议开发者通过 JShell 的文档了解更多信息。

文章翻译自:https://developers.redhat.com/blog/2019/04/05/10-things-developers-need-to-know-about-jshell/

原文链接:https://my.oschina.net/javayou/blog/3032949
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章