JDK 9 is finally here. Let’s talk about it. This is the first post in the Java 9 series, which covers various new features in the latest release of the JDK. We’ll start with an exciting new tool – JShell.
JShell, described in detail in JEP 222, is Java’s implementation of REPL, Read-Eval-Print-Loop. It’s a tool that loops, continually reads user input, evaluates it, and prints out the output. It’s simply an interactive command line as you know it from other stacks, such as Scala, Groovy, or Python. Starting with JDK 9, Java has an official REPL too!
Although REPL was added to the JDK primarily as a means of lowering the barrier to entry for learners of the language, it can actually be a useful tool for experienced developers as well – it’s great for prototyping, exploring new APIs, or just trying out simple code, possibly as a reminder of how specific APIs work when you come back to your Java project after working on something different for a while. I’ve also used the tool when interviewing candidates for a Java development position.
If you have Java 9 in your
$PATH, you can easily start the tool:
The main thing you need to know about JShell is that it accepts two types of inputs – snippets, the actual Java code to evaluate, and commands to the tool (starting with
To demonstrate the basic functionality, let’s start with a simple expression:
You can see two interesting things here –
1 + 1 = 2, and the result has been assigned to something called
$1. That’s an implicit variable JShell created for us, and it does that whenever we use an expression and don’t assign it to anything ourselves. We could, of course, create our own, explicit variable:
Or submit a statement:
There are a few tricks you can use with JShell to prototype faster. As you’ve probably noticed, we didn’t need to wrap expressions in any context, we can just type them directly. Similarly, we didn’t need to place a semicolon after our statement above (or any other single-statement snippets in general). We also don’t need to catch checked exceptions in these cases, for example:
We can use quite a few APIs by default, thanks to the default imports performed at startup. This brings us to the first command,
/imports, which lists all the performed imports, including the default ones:
This is not all of the JDK, so you might need to import additional APIs. For instance:
/imports, there are commands for listing declared variables and used snippets, or
By the way, JShell supports prefix matching on commands, as long as we specify a unique prefix:
We can also declare methods and types, and list them with their respective
Of course, it’s possible to remove declared items, as well as edit them using the default retro-looking editor, or whatever editor you have in your
EDITOR environment variable:
Furthermore, you can use the
/help command to discover some advanced features of the tool:
As far as editing capabilities go, JShell supports line editing as per the Emacs editing mode, similarly to what’s described in Editing modes and shortcuts in JBoss CLI. There are also a few handy keyboard shortcuts:
Finally, it should be noted that JShell is backed by an API, and you can take advantage of its functionality in your applications. Let’s try to evaluate the first example in this post using JShell’s API:
For more information, check out my talks on JShell from Devoxx US and JavaOne.