在今年九月正式发布的 Java9 版本中,其 /bin 目录中多个一个交互工具 JShell(据说 Java8 已有测试版)。众所周知,许多编程语言都提供称作 Read-Evaluate-Print Loop (REPL)的命令行工具,它们能够在输入声明、语句及表达式时计算,并立即给出结果。
以 Python 为例,运行整个工程、项目可能需要很长时间,但是你可以使用此工具执行一些需要确定的表达式,就能立即得到他们返回的值。这对于哪些开始学习语言或者接触语言新功能的程序员来说是个便捷好用的工具。
然而没 JShell 之前的 Java 来说,你需要编写一个测试类新建 main 方法来打印结果,并且每次修改后需要重写编译、运行。
运行
下载并安装 Java9 ,配置环境变量,或者不配置的话直接在 /bin 目录下就能找到 jshell 可执行文件。建议一开始运行加入 -v 参数,JShell 给出详细反馈。
root@Mydebian:~$ jdk-9/bin/jshell -v
| 欢迎使用 JShell -- 版本 9
| 要大致了解该版本, 请键入: /help intro
jshell>
此时不需要详情模式,可输入 /set feedback normal
默认导入
JShell 默认有一组常用的导入
jshell> /imports
| import java.util.*、
| import java.io.*
| import java.math.*
| import java.net.*
| import java.util.concurrent.*
| import java.util.prefs.*
| import java.util.regex.*
你也可以任何时候导入自己想要的通过 import XXX (单击 tab 补全、给出可选)
表达式
你可以输入任何有效的 Java 表达式,它将得出返回值、类型,并分配给一个变量,如:
jshell> 3+3
$1 ==> 6
| 已创建暂存变量 $1 : int
jshell> $1
$1 ==> 6
| $1 的值: in
变量
可以声明变量(默认值),并赋值。一旦声明后,变量即为当前对话中全局变量,再次声明、赋值将覆盖
jshell> int x=5
x ==> 5
| 已创建 变量 x : int
jshell> x
x ==> 5
| x 的值: int
方法
也可以定义方法,再次定义将覆盖
jshell> void hello() { System.out.println("Hello JShell"); }
| 已创建 方法 hello()
jshell> hello()
Hello JShell
jshell> void hello() { System.out.println("Replace Method"); }
| 已修改 方法 hello()
| 更新已覆盖 方法 hello()
jshell> hello()
Replace Method
不过尝试了下,发现 JShell 定义方法只支持参数重载,不支持返回值重载,后定义将覆盖前面定义的
jshell> void hello() { System.out.println("Void No Param"); }
| 已创建 方法 hello()
jshell> void hello(int x) { System.out.println("Void INT Param"); }
| 已创建 方法 hello(int)
jshell> /methods
| void hello()
| void hello(int)
jshell> int hello(int x) { System.out.println("Int INT Param");return x; }
| 已替换 方法 hello(int)
| 更新已覆盖 方法 hello(int)
jshell> /methods
| void hello()
| int hello(int)
jshell> int hello() { System.out.println("Int No Param");return 1; }
| 已替换 方法 hello()
| 更新已覆盖 方法 hello()
jshell> /methods
| int hello(int)
| int hello()
命令
除了 Java 代码外,你还可以执行一些 JShell 命令。一些常用的如下(键入 help 将列举所有)
列出变量
jshell> /vars
| int x = 0
| double j = 0.5
列出方法
jshell> /methods
| printf (String,Object...)void
| hello ()void
列出执行过的代码
jshell> /list
1 : 3+3
2 : $1
4 : x
5 : int y;
6 : y
7 : x
8 : int x;
10 : hello()
11 : void hello() { System.out.println("Replace Method"); }
12 : hello()
编辑
jshell> /edit hello
可以后跟方法名(将编辑所有重载方法)、变量名、id。id 就是上面通过 /list 列出的序号。
使用示例
验证返回值
jshell> 1.0/2
$6 ==> 0.5
| 已创建暂存变量 $6 : double
jshell> 1/2.0
$7 ==> 0.5
| 已创建暂存变量 $7 : double
jshell> 1/2.0f
$8 ==> 0.5
| 已创建暂存变量 $8 : float
jshell> 1.0f/2
$9 ==> 0.5
| 已创建暂存变量 $9 : float
jshell> 1.0f/2.0f
$10 ==> 0.5
| 已创建暂存变量 $10 : float
jshell> 1.0f/2.0
$11 ==> 0.5
| 已创建暂存变量 $11 : double
装箱细节
jshell> Integer i1=127
i1 ==> 127
| 已创建 变量 i1 : Integer
jshell> Integer i2=127
i2 ==> 127
| 已创建 变量 i2 : Integer
jshell> i1==i2
$14 ==> true
| 已创建暂存变量 $14 : boolean
jshell> Integer i1=128
i1 ==> 128
| 已修改 变量 i1 : Integer
| 更新已覆盖 变量 i1 : Integer
jshell> Integer i2=128
i2 ==> 128
| 已修改 变量 i2 : Integer
| 更新已覆盖 变量 i2 : Integer
jshell> i1==i2
$17 ==> false
| 已创建暂存变量 $17 : boolean
值在-128-127的自动装箱 Integer 对象在JVM中已经缓存好
jshell> Integer i1= new Integer(127)
i1 ==> 127
| 已修改 变量 i1 : Integer
| 更新已覆盖 变量 i1 : Integer
jshell> Integer i2= 127
i2 ==> 127
| 已修改 变量 i2 : Integer
| 更新已覆盖 变量 i2 : Integer
jshell> i1==i2
$29 ==> false
| 已创建暂存变量 $29 : boolean
总结
JShell 这一REPL交互工具,将给测试 Java 代码片段带来很大的方便。Java 程序员将像 Python、NodeJS、Scala程序员那样享受这种命令行带来的便捷,看到这里还不行动起来?下载个试试,将让你回想起自己写 main 测试就想流泪 XD
资料
- Java Download
- JShell Doc
- [JAKUB DZIWORSKI`s BLOG](http://jakubdziworski.github.io/java/2016/07/31/jshell-getting-started-examples.html)