Java 9 – Exploring the REPL – Java 9 – 探索 REPL

最后修改: 2017年 3月 1日


1. Introduction


This article is about jshell, an interactive REPL (Read-Evaluate-Print-Loop) console that is bundled with the JDK for the upcoming Java 9 release. For those not familiar with the concept, a REPL allows to interactively run arbitrary snippets of code and evaluate their results.

本文是关于jshell,一个交互式的REPL(Read-Evaluate-Print-Loop)控制台,它被捆绑在即将发布的Java 9的JDK上。对于那些不熟悉这个概念的人来说,REPL允许交互式地运行任意的代码片断并评估其结果。

A REPL can be useful for things such as quickly checking the viability of an idea or figuring out e.g. a formatted string for String or SimpleDateFormat.


2. Running


To get started we need to run the REPL, which is done by invoking:



If more detailed messaging from the shell is desired, a -v flag can be used:


$JAVA_HOME/bin/jshell -v

Once it is ready, we will be greeted by a friendly message and a familiar Unix-style prompt at the bottom.


3. Defining and Invoking Methods


Methods can be added by typing their signature and body:


jshell> void helloWorld() { System.out.println("Hello world");}
|  created method helloWorld()

Here we defined the ubiquitous “hello world” method. It can be invoked using normal Java syntax:

这里我们定义了无处不在的 “hello world “方法。 它可以用正常的Java语法来调用。

jshell> helloWorld()
Hello world

4. Variables


Variables can be defined with the normal Java declaration syntax:


jshell> int i = 0;
i ==> 0
|  created variable i : int

jshell> String company = "Baeldung"
company ==> "Baeldung"
|  created variable company : String

jshell> Date date = new Date()
date ==> Sun Feb 26 06:30:16 EST 2017
|  created variable date : Date

Note that semicolons are optional. Variables can also be declared without initialization:

注意,分号是可选的。 变量的声明也可以不进行初始化。

jshell> File file
file ==> null
|  created variable file : File

5. Expressions


Any valid Java expression is accepted and the result of the evaluation will be shown. If no explicit receiver of the result is provided, “scratch” variables will be created:

任何有效的Java表达式都可以被接受,并且评估的结果将被显示。如果没有提供明确的结果接收器,将创建 “scratch “变量。

jshell> String.format("%d of bottles of beer", 100)
$6 ==> "100 of bottles of beer"
|  created scratch variable $6 : String

The REPL is quite helpful here by informing us that it created a scratch variable named $6 which value is “100 of bottles of beer on the wall” and its type is String.

REPL在这里很有帮助,它告诉我们它创建了一个名为$6的变量,其值为 “墙上的100瓶啤酒”,其类型为String

Multi-line expressions are also possible. Jshell is smart enough to know when an expression is incomplete and will prompt the user to continue on a new line:

多行表达式也是可能的。 Jshell足够聪明,知道什么时候表达式是不完整的,并将提示用户在新的一行中继续:

jshell> int i =
   ...> 5;
i ==> 5
|  modified variable i : int
|    update overwrote variable i : int

Note how the prompt changed to an indented …> to signify the continuation of an expression.


6. Commands


Jshell provides quite a few meta-commands that aren’t related to evaluating Java statements. They all start with a forward-slash (/) to be distinguished from normal operations. For example, we can request a list of all available commands by issuing /help or /?.

Jshell提供了许多与评估Java语句无关的元命令。 它们都以正斜杠(/)开始,以区别于正常操作。例如,我们可以通过发出/help或者/? 来请求一个所有可用命令的列表。

Let’s take a look at some of them.


6.1. Imports


To list all the imports active in the current session we can use the /import command:


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

As we can see, the shell starts with quite a few useful imports already added.


6.2. Lists


Working in a REPL is not nearly as easy as having a full-featured IDE at our fingertips: it is easy to forget what variables have which values, what methods have been defined and so on. To check the state of the shell we can use /var, /methods, /list or /history:

在REPL中工作并不像在我们的指尖上有一个全功能的IDE那样容易:我们很容易忘记哪些变量有哪些值,哪些方法已经被定义等等。 要检查shell的状态,我们可以使用/var/methods/list/history:

jshell> /var
| int i = 0
| String company = "Baeldung"
| Date date = Sun Feb 26 06:30:16 EST 2017
| File file = null
| String $6 = "100 of bottles of beer on the wall"

jshell> /methods
| void helloWorld()

jshell> /list

 1 : void helloWorld() { System.out.println("Hello world");}
 2 : int i = 0;
 3 : String company = "Baeldung";
 4 : Date date = new Date();
 5 : File file;
 6 : String.format("%d of bottles of beer on the wall", 100)

jshell> /history

void helloWorld() { System.out.println("Hello world");}
int i = 0;
String company = "Baeldung"
Date date = new Date()
File file
String.format("%d of bottles of beer on the wall", 100)

The difference between /list and /history is that the latter shows commands in addition to expressions.


6.3. Saving


To save the expression history the /save command can be used:


jshell> /save

This saves our expression history into in the same directory from which we ran the jshell command.


6.4. Loading


To load a previously saved file we can use the /open command:


jshell> /open

A loaded session can then be verified by issuing /var, /method or /list.


6.5. Exiting


When we are done with the work, the /exit command can terminate the shell:


jshell> /exit
|  Goodbye

Goodbye jshell.


7. Conclusion


In this article, we took a look at Java 9 REPL. Since Java has been around for over 20 years already, perhaps it arrived a little late. However, it should prove to be another valuable tool in our Java toolbox.

在这篇文章中,我们看了一下Java 9 REPL。由于Java已经有20多年的历史了,也许它来得有点晚。但是,它应该被证明是我们Java工具箱中的另一个有价值的工具。