在jdk9中包含了一个REPL形式的交互式shell工具,它可以实时反馈java语法的运行结果,下面做一下简单介绍

准备

需要安装jdk9

运行

将jdk9的bin目录配置到path目录并在命令行运行jshell,或cd到jdk9的bin目录直接运行jshell,就可以进入jshell的命令提示符

bin>jshell.exe
|  欢迎使用 JShell -- 版本 9
|  要大致了解该版本, 请键入: /help intro

jshell>

之后可以键入想要运行的代码

jshell> String name="world"
name ==> "world"

jshell> void hello(String name){
   ...> System.out.println("hello "+name);
   ...> }
|  已创建 方法 hello(String)

jshell> hello(name)
hello world

可以看到这里并不需要按java语法创建类,以及main方法,每条命令都会实时返回结果,而且命令结束的分号是可选的(但方法内的代码的分号不可省略)。
如果方法中有依赖其他变量或方法也不会影响方法创建,jshell能自动识别,但只有所有依赖都创建完,这个方法才可被运行

jshell> int circumference(int r){
   ...> return 2*PI*r;
   ...> }
|  已创建 方法 circumference(int), 不过, 它无法调用, 直至 variable PI 已声明

由于没有定义PI常量,虽然方法创建了,但不能运行。
重复定义方法或变量可以覆盖原有的方法/变量
如果需要import其他数据类型,有两种方法,一个是输入import XXXX,还有一种是new对象时,按shift+tab,释放后按i,之后会有提示,按提示就可import对应的类

jshell> new JFrame <shift+tab> <i>
0: 不执行任何操作
1: import: javax.swing.JFrame
选项:
Imported: javax.swing.JFrame

jshell> new JFrame

shift+tab释放后按v可以快速为当前行的命令创建变量,

jshell> new BigDecimal(1) <shift+tab> <v>
jshell> BigDecimal | = new BigDecimal(1)

光标会自动移到|位置,供用户输入
当代码抛出异常时,异常的信息的堆栈会打印成(snippetId:行号)的形式,其中snippetId是所有变量/方法被分配的递增编号

jshell> void ex(){
   ...> throw new RuntimeException();
   ...> }
|  已创建 方法 ex()

jshell> ex()
|  java.lang.RuntimeException thrown:
|        at ex (#1:2)
|        at (#2:1)

command

除了普通java语言,jshell还有一些command,这里介绍一些常用的,其他可以通过/help查看
/exit 退出jshell
/list 显示所有创建的变量和方法(Snippets)

jshell> /list -all
  s1 : import java.io.*;
  s2 : import java.math.*;
  s3 : import java.net.*;
  s4 : import java.nio.file.*;
  s5 : import java.util.*;
  s6 : import java.util.concurrent.*;
  s7 : import java.util.function.*;
  s8 : import java.util.prefs.*;
  s9 : import java.util.regex.*;
 s10 : import java.util.stream.*;
   1 : import javax.swing.JFrame;
   2 : BigDecimal a = new BigDecimal(1);

-all参数显示所有snippets,每行冒号前是snippetId,s开头的是默认加载的snippets,这里引用了常用的包
/save <文件名> 保存当前snippets,会将当前所有snippets保存成文本形式
/open <文件名> 加载保存的snippets,jshell默认提供了几个script DEFAULT:默认启动引用的package PRINTING:简化打印方法的调用,免去输入System.out JAVASE:引入javaSe的package
/env --class-path <classPath> 定义classpath用于引入外部依赖的包