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限制与注意事项
- 没有包声明:不能写
package com.example; - 没有 import 语句(部分):可以 import,但不需要完整路径
- 没有访问修饰符限制:默认 public,不需要加
public - 语句必须完整:不能跨行输入半个语句(可以用
...>继续) - 不是生产工具:适合实验和学习,不适合写生产代码
进阶技巧
使用 /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 不够好用:
| 工具 | 说明 |
|---|---|
| jshell | JDK 内置,够用 |
| IDE 交互窗口 | IntelliJ IDEA/VSCode 都有 REPL 插件 |
| JShell API | 可以嵌入到自己的应用里 |
小结
JShell 是 JDK 9 最实用的新工具之一:
- 学习新 API:不用写临时文件,直接试
- 验证想法:写几行代码看结果
- 调试表达式:不用创建临时变量
- 教学演示:边讲边跑给学生看
记住退出命令是 /exit,不是 quit 或 exit。
