与JShell一起舞动代码的魔法:Java9交互式编程体验

简介: 与JShell一起舞动代码的魔法:Java9交互式编程体验

什么是交互式编程环境?重点词交互,在这样的编程环境中,你每输入一行代码,环境都会给你一个反馈,这就是交互式的编程环境。这种编程环境并不太适合工程化的复杂性需求,但在一些快速验证、简单计算之类的场景下还是非常好用的。其实交互式编程环境在其他高级语言中很早就有了,而 Java 直到 Java 9 才正式推出了这样的工具。

下面就来一起学习下,这个 Java 中的交互式编程环境 JShell

快速入门

启动 JShell

打开终端,然后执行命令:jshell,执行效果如下:

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

执行计算

在 jshell 中可以快速的执行计算操作并获得结果,比如这样:

jshell> 1+2
$1 ==> 3

定义变量

在 jshell 中也可以定义变量与函数,比如,你可以这样定义变量,并进行计算:

jshell> int a=1, b=2;
a ==> 1
b ==> 2
jshell> int c = a + b
c ==> 3

定义函数

在 jshell 中也可以函数来封装操作,比如下面就是一个定义求和函数并调用它的例子:

jshell> int sum(int a, int b){
   ...>     return a + b;
   ...> }
|  已创建 方法 sum(int,int)
jshell> int c = sum(1, 2)
c ==> 3

定义类

在 jshell 中,定义一些简单的类,也是可以实现的,比如:

jshell> public class Calculate {
   ...>
   ...>     public int a;
   ...>     public int b;
   ...>
   ...>     public int sum() {
   ...>         return a + b;
   ...>     }
   ...> }
|  已创建 类 Calculate
jshell> Calculate c = new Calculate();
c ==> Calculate@4fca772d
jshell> c.a = 1
$9 ==> 1
jshell> c.b = 2
$10 ==> 2
jshell> c.sum()
$11 ==> 3

当然了,这种场景其实就已经比较复杂了,这里其实搭配 Java 16 中新增的 record 来实现的话,会简单实用一些。

查看命令:/help

关于 jshell 常用命令,我们可以通过 /help 来查看:

jshell> /help
|  键入 Java 语言表达式, 语句或声明。
|  或者键入以下命令之一:
|  /list [<名称或 id>|-all|-start]
|   列出您键入的源
|  /edit <名称或 id>
|   编辑源条目
|  /drop <名称或 id>
|   删除源条目
|  /save [-all|-history|-start] <文件>
|   将片段源保存到文件
|  /open <file>
|   打开文件作为源输入
|  /vars [<名称或 id>|-all|-start]
|   列出已声明变量及其值
|  /methods [<名称或 id>|-all|-start]
|   列出已声明方法及其签名
|  /types [<名称或 id>|-all|-start]
|   列出类型声明
|  /imports
|   列出导入的项
|  /exit [<integer-expression-snippet>]
|   退出 jshell 工具
|  /env [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>] ...
|   查看或更改评估上下文
|  /reset [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>]...
|   重置 jshell 工具
|  /reload [-restore] [-quiet] [-class-path <路径>] [-module-path <路径>]...
|   重置和重放相关历史记录 -- 当前历史记录或上一个历史记录 (-restore)
|  /history [-all]
|   您键入的内容的历史记录
|  /help [<command>|<subject>]
|   获取有关使用 jshell 工具的信息
|  /set editor|start|feedback|mode|prompt|truncation|format ...
|   设置配置信息
|  /? [<command>|<subject>]
|   获取有关使用 jshell 工具的信息
|  /!
|   重新运行上一个片段 -- 请参阅 /help rerun
|  /<id>
|   按 ID 或 ID 范围重新运行片段 -- 参见 /help rerun
|  /-<n>
|   重新运行以前的第 n 个片段 -- 请参阅 /help rerun
|
|  有关详细信息, 请键入 '/help', 后跟
|  命令或主题的名称。
|  例如 '/help /list' 或 '/help intro'。主题:
|
|  intro
|   jshell 工具的简介
|  keys
|   类似 readline 的输入编辑的说明
|  id
|   片段 ID 以及如何使用它们的说明
|  shortcuts
|   片段和命令输入提示, 信息访问以及
|   自动代码生成的按键说明
|  context
|   /env /reload 和 /reset 的评估上下文选项的说明
|  rerun
|   重新评估以前输入片段的方法的说明
jshell> /help
|  键入 Java 语言表达式, 语句或声明。
|  或者键入以下命令之一:
|  /list [<名称或 id>|-all|-start]
|   列出您键入的源
|  /edit <名称或 id>
|   编辑源条目
|  /drop <名称或 id>
|   删除源条目
|  /save [-all|-history|-start] <文件>
|   将片段源保存到文件
|  /open <file>
|   打开文件作为源输入
|  /vars [<名称或 id>|-all|-start]
|   列出已声明变量及其值
|  /methods [<名称或 id>|-all|-start]
|   列出已声明方法及其签名
|  /types [<名称或 id>|-all|-start]
|   列出类型声明
|  /imports
|   列出导入的项
|  /exit [<integer-expression-snippet>]
|   退出 jshell 工具
|  /env [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>] ...
|   查看或更改评估上下文
|  /reset [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>]...
|   重置 jshell 工具
|  /reload [-restore] [-quiet] [-class-path <路径>] [-module-path <路径>]...
|   重置和重放相关历史记录 -- 当前历史记录或上一个历史记录 (-restore)
|  /history [-all]
|   您键入的内容的历史记录
|  /help [<command>|<subject>]
|   获取有关使用 jshell 工具的信息
|  /set editor|start|feedback|mode|prompt|truncation|format ...
|   设置配置信息
|  /? [<command>|<subject>]
|   获取有关使用 jshell 工具的信息
|  /!
|   重新运行上一个片段 -- 请参阅 /help rerun
|  /<id>
|   按 ID 或 ID 范围重新运行片段 -- 参见 /help rerun
|  /-<n>
|   重新运行以前的第 n 个片段 -- 请参阅 /help rerun
|
|  有关详细信息, 请键入 '/help', 后跟
|  命令或主题的名称。
|  例如 '/help /list' 或 '/help intro'。主题:
|
|  intro
|   jshell 工具的简介
|  keys
|   类似 readline 的输入编辑的说明
|  id
|   片段 ID 以及如何使用它们的说明
|  shortcuts
|   片段和命令输入提示, 信息访问以及
|   自动代码生成的按键说明
|  context
|   /env /reload 和 /reset 的评估上下文选项的说明
|  rerun
|   重新评估以前输入片段的方法的说明

查看定义的函数:/methods

jshell> /methods
|    int sum(int,int)

查看定义的变量:/vars

jshell> /vars
|    int $1 = 3
|    int b = 2
|    Calculate c = Calculate@4fca772d
|    int $9 = 1
|    int $10 = 2
|    int $11 = 3
|    int $13 = 3

列出输入源条目:/list

执行后,可以看到之前在 jshell 中输入的内容清单:

jshell> /list
   1 : 1+2
   3 : int a=1, b=2;
   5 : int sum(int a, int b){
           return a + b;
       }
   7 : public class Calculate {
           public int a;
           public int b;
           public int sum() {
               return a + b;
           }
       }
   8 : Calculate c = new Calculate();
   9 : c.a = 1
  10 : c.b = 2
  11 : c.sum()
  12 : Map a = new HashMap();

左侧的数字为条目 id,可以利用该 id,进行编辑和删除操作。

编辑源条目:/edit

上面通过 /list 列出了输入的条目信息,下面试试通过 /edit 编辑下,比如:

jshell> /edit 7

此时会弹出修改框,修改完成后,点击 accept 即可。

删除源条目:/drop

/drop 命令可以用来删除某个源条目,比如我们可以用下面的命令删除 id 为 12 的那行。

jshell> /drop 12
|  已删除 变量 a

保存文件:/save

如果想把这次编辑的内容保存下来,以便到其他环境执行,或者下次继续使用的话,可以通过 /save 来保存到文件里,比如这样:

jshell> /save aaa.txt

打开文件:/open

当我们换了一个 jshell 环境后,可以通过打开之前保存的文件来快速还原之前的执行内容,比如:

jshell> /open aaa.txt

重置 jshell:/reset

当我们要换一个内容编写的时候,需要清空之前执行的条目(清空 /list 的内容),这个时候就可以这样来实现:

jshell> /reset
|  正在重置状态。

查看引入的包:/imports

jshell> /imports
|    import java.io.*
|    import java.math.*
|    import java.net.*
|    import java.nio.file.*
|    import java.util.*
|    import java.util.concurrent.*
|    import java.util.function.*
|    import java.util.prefs.*
|    import java.util.regex.*
|    import java.util.stream.*

查看定义的类:/types

jshell> /types
|    class Calculate

退出 jshell:/exit

jshell> /exit
| Goodbye 


相关文章
|
24天前
|
Java 程序员
Java编程中的异常处理:从基础到高级
在Java的世界中,异常处理是代码健壮性的守护神。本文将带你从异常的基本概念出发,逐步深入到高级用法,探索如何优雅地处理程序中的错误和异常情况。通过实际案例,我们将一起学习如何编写更可靠、更易于维护的Java代码。准备好了吗?让我们一起踏上这段旅程,解锁Java异常处理的秘密!
|
4天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
8天前
|
算法 Java 调度
java并发编程中Monitor里的waitSet和EntryList都是做什么的
在Java并发编程中,Monitor内部包含两个重要队列:等待集(Wait Set)和入口列表(Entry List)。Wait Set用于线程的条件等待和协作,线程调用`wait()`后进入此集合,通过`notify()`或`notifyAll()`唤醒。Entry List则管理锁的竞争,未能获取锁的线程在此排队,等待锁释放后重新竞争。理解两者区别有助于设计高效的多线程程序。 - **Wait Set**:线程调用`wait()`后进入,等待条件满足被唤醒,需重新竞争锁。 - **Entry List**:多个线程竞争锁时,未获锁的线程在此排队,等待锁释放后获取锁继续执行。
35 12
|
4天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
20 3
|
4天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
52 2
|
11天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
49 2
|
27天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
27天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
21天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
21天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
44 3