Skip to content

JShell

写 Java 这么多年,有没有想过——能不能像 Python 那样,写一行代码直接跑?

答案是能。JDK 9 引入了 JShell,Java 自己的交互式编程环境。

快速体验

bash
# 启动 JShell
$ jshell
|  Welcome to JShell -- Version 17
|  For an introduction type: /help intro

jshell> int x = 10
x ==> 10

jshell> int y = 20
y ==> 20

jshell> x + y
$3 ==> 30

jshell> /exit
|  Goodbye

不需要创建文件、不需要编译,直接输入表达式就能看到结果。这就是 JShell 的核心价值。

常用命令

命令说明
/help显示帮助
/help intro入门介绍
/list列出当前 session 的所有代码片段
/list -all列出所有,包括历史
/vars列出当前定义的变量
/methods列出当前定义的方法
/types列出当前定义的类型
/edit打开编辑器编辑代码片段
/drop删除某个代码片段
/save保存 session 到文件
/open加载文件到 session
/reset重置 session
/exit退出

基础用法

变量

bash
jshell> int count = 0
count ==> 0

jshell> String name = "Java"
name ==> "Java"

jshell> boolean active = true
active ==> true

# 修改变量
jshell> count = 5
count ==> 5

# JShell 自动为表达式生成变量名
jshell> 3 + 5
$6 ==> 8

jshell> "Hello".length()
$7 ==> 5

方法定义

bash
jshell> int add(int a, int b) {
   ...>     return a + b;
   ...> }
|  created method add(int,int)

jshell> add(3, 5)
$9 ==> 8

jshell> String greet(String name) {
   ...>     return "Hello, " + name;
   ...> }
|  created method greet(String)

jshell> greet("JShell")
$11 ==> "Hello, JShell"

类和方法都能定义

bash
jshell> class Calculator {
   ...>     private int result = 0;
   ...>     
   ...>     public void add(int n) {
   ...>         result += n;
   ...>     }
   ...>     
   ...>     public int getResult() {
   ...>         return result;
   ...>     }
   ...> }
|  created class Calculator

jshell> Calculator calc = new Calculator()
calc ==> Calculator@6d00e490

jshell> calc.add(10)
jshell> calc.add(20)
jshell> calc.getResult()
$16 ==> 30

实用场景

场景一:测试 JDK API

bash
# 测试字符串方法
jshell> "hello world".toUpperCase()
$1 ==> "HELLO WORLD"

# 测试集合
jshell> List<String> list = List.of("a", "b", "c")
list ==> [a, b, c]

jshell> list.stream().map(String::toUpperCase).toList()
$3 ==> [A, B, C]

# 测试 Optional
jshell> Optional<String> opt = Optional.ofNullable(null)
opt ==> Optional.empty

jshell> opt.orElse("default")
$5 ==> "default"

# 测试正则
jshell> "hello123".replaceAll("\\d+", "_")
$6 ==> "hello_"

场景二:快速验证算法

bash
jshell> int fibonacci(int n) {
   ...>     if (n <= 1) return n;
   ...>     return fibonacci(n - 1) + fibonacci(n - 2);
   ...> }
|  created method fibonacci(int)

jshell> IntStream.range(0, 10).mapToObj(this::fibonacci).toList()
$2 ==> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

场景三:调试复杂表达式

bash
# 不用 JShell,你得写临时变量、打印、再删掉
jshell> List<Integer> numbers = List.of(1, 2, 3, 4, 5)
numbers ==> [1, 2, 3, 4, 5]

jshell> numbers.stream().filter(n -> n % 2 == 0).map(n -> n * n).toList()
$3 ==> [4, 16]

场景四:实验新特性

bash
# JDK 14+ 的文本块
jshell> String json = """
   ...> {
   ...>     "name": "Java",
   ...>     "version": 21
   ...> }
   ...> """
json ==> "
{
    "name": "Java",
    "version": 21
}
"

外部执行

JShell 脚本可以直接从文件执行:

bash
# 创建脚本文件
$ cat > hello.jsh << 'EOF'
System.out.println("Hello from JShell script!");
int add(int a, int b) {
    return a + b;
}
System.out.println("3 + 5 = " + add(3, 5));
EOF

# 执行脚本
$ jshell hello.jsh
Hello from JShell script!
3 + 5 = 8

限制与注意事项

  1. 没有包声明:不能写 package com.example;
  2. 没有 import 语句(部分):可以 import,但不需要完整路径
  3. 没有访问修饰符限制:默认 public,不需要加 public
  4. 语句必须完整:不能跨行输入半个语句(可以用 ...> 继续)
  5. 不是生产工具:适合实验和学习,不适合写生产代码

进阶技巧

使用 /set 命令自定义

bash
# 设置编辑器和反馈选项
jshell> /set editor vim
jshell> /set feedback verbose

# 保存设置
jshell> /set start -retain

从外部加载类

bash
# 启动时加载 classpath
$ jshell --class-path mylib.jar

# 在 JShell 内使用
jshell> import com.example.MyClass;
jshell> new MyClass()

调试模式

bash
# 显示详细信息
$ jshell -v

# 显示命令执行跟踪
jshell> /set trace true

替代方案

如果觉得 JShell 不够好用:

工具说明
jshellJDK 内置,够用
IDE 交互窗口IntelliJ IDEA/VSCode 都有 REPL 插件
JShell API可以嵌入到自己的应用里

小结

JShell 是 JDK 9 最实用的新工具之一:

  • 学习新 API:不用写临时文件,直接试
  • 验证想法:写几行代码看结果
  • 调试表达式:不用创建临时变量
  • 教学演示:边讲边跑给学生看

记住退出命令是 /exit,不是 quitexit

基于 VitePress 构建