关于 JDK 9 中的 JShell,你应该了解的 10 件事
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/
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
LevelDB源码分析-Get
Get LevelDB提供了Get接口用于给定key的查找: Status DBImpl::Get(const ReadOptions &options, const Slice &key, std::string *value) Get操作可以指定在某个snapshot的情况下进行,如果指定了snapshot,则获取该snapshot的sequencenumber,如果没有指定snapshot,就取当前最新的sequencenumber: Status s; MutexLock l(&mutex_); SequenceNumber snapshot; if (options.snapshot != nullptr) { snapshot = static_cast<const SnapshotImpl *>(options.snapshot)->sequence_number(); } else { snapshot = versions_->LastSequence(); } MemTable *mem = mem_; MemTabl...
- 下一篇
深度解析RocketMQ消息发送的高可用设计
微信公众号「后端进阶」,专注后端技术分享:Java、Golang、WEB框架、分布式中间件、服务治理等等。 老司机倾囊相授,带你一路进阶,来不及解释了快上车! 从rocketmq topic的创建机制可知,一个topic对应有多个消息队列,那么我们在发送消息时,是如何选择消息队列进行发送的?假如这时有broker宕机了,rocketmq是如何规避故障broker的?看完这篇文章,相信你会从文中找到答案。 rocketmq在发送消息时,由于nameserver检测broker是否还存活是有延迟的,在选择消息队列时难免会遇到已经宕机的broker,又或者因为网络原因发送失败的,因此rocketmq采取了一些高可用设计的方案,主要通过两个手段:重试与Broker规避。 重试机制 直接定位到client端发送消息的方法: org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendDefaultImpl: int timesTotal = communicationMode == CommunicationMode.SY...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程