JShell - Java交互工具(REPL) - 笔记

在今年九月正式发布的 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

资料

觉得不错不妨打赏一笔