JShell: The new Java 9 REPL
Don't miss an opportunity to take JShell, the new Java 9 REPL, for a test drive. An expert shares his experience.
"What is an REPL?" you ask. An REPL is a command-line tool for quickly running statements.
In my description, the word "statements" is important. In Java, you normally don't run a single statement or a collection of statements. Instead, you run an entire compilation unit (a main class or a collection of classes). But with the new Java 9 REPL, you can run a single statement (a simple statement, a compound statement, or a statement whose meaning depends on some of your earlier statements).
The acronym REPL stands for Read-Evaluate-Print-Loop. Many languages (most notably, the scripting languages) already have REPL tools. Java has a few third-party REPL tools, including Java REPL and BeanShell. But with Java 9, to be released in 2016, the SDK will come with an official REPL named JShell (and codenamed Kulla).
In the formal proposal for JShell (JEP 222), the project's members describe the motivation for creating a Java REPL:
Immediate feedback is important when learning a programming language. The number one reason schools cite for moving away from Java as a teaching language is that other languages have a "REPL" and have far lower bars to an initial "Hello, world!" program.
In fact, in recent years, colleges have moved away from Java as a first language in favor of Python , in which print("Hello, World!")
is a complete, executable program. But the new JShell REPL isn't only for students. Developers can use JShell to do a quick check on some complex programming logic.
The formal proposal for JShell emphasizes that the REPL stays faithful to Java, and does not implement a brand new scripting language:
… if X is an input that JShell accepts (as opposed to rejects with error) then there is an A and B such that AXB is a valid program in the Java programming language.
You can try it
To get a sense of the way JShell works, start by installing the Java 9 Early Access JDK. Then download the Kulla 0.710 Jar file from cloudbees.com. Run the REPL tool by typing a command of the following kind in a Terminal or Command Prompt (cmd) window:
java -jar kulla.jar
Remember to point to the locations of Java and the Kulla Jar file on your directory system, and to use the name of the Jar file that you downloaded from cloudbees.com:
path-to-jdk9/bin/java -jar path-to-downloaded-jar-file/name-of-the-downloaded-jar-file
For example, on my Windows computer, I type
c:\Program Files\Java\jdk1.9.0\bin\java -jar \MyJarFiles\kulla-0.710-20150717005839.jar
Working with JShell
Once it's running, you can converse with JShell as if you're in the middle of a bona fide Java class. The following is a transcript of one of my JShell sessions:
As the following example shows, you can save your work during a JShell session, and reopen your work in the same session or during a subsequent session:
In the example above, the file created by JShell (the myGreetings.txt file) is a simple text file:
System.out.println("Hello")
System.out.println("Goodbye")
You can use the /open command to scoop up an entire Java class -- a class that you declared in Eclipse, IntelliJ IDEA, or in any text editor.
Dependencies in class definitions are handled gracefully, as you can see from the following example:
Adding, replacing and modifying code snippets
JShell lets you redeclare and edit your variables, methods and classes. The following example illustrates the redeclaration and editing features:
At this point, JShell launches a tiny text editor. I change the text in the editor: then I click Accept and Exit.
These redeclaring and editing features are convenient, but they're not without risks. The following is an example in which there are no surprises:
The example ends with a NullPointerException
. Having changed the field type in the MyThing
class, the previously declared instance of MyThing
no longer exists. In my view, that's a fairly safe outcome.
But notice what happens when I make a less drastic change to the MyThing
class:
Both thing1
and thing2
were declared using the MyThing
default constructor, but the fields in thing1
and thing2
have different values.
When you bring home a gizmo with some assembly required, it helps to read the instructions. And the same holds true for JShell. When I change the MyThing
field from an int
to a double
, JShell displays a Replaced class MyThing
notification and reminds me that Update replaced variable thing1, reset to null
. But when I simply change the field's initial value, JShell says Modified class MyThing
and says nothing about thing1.
Sure enough, the formal proposal for JShell distinguishes between adding, modifying and replacing a code snippet:
A snippet is Added if it is the first declaration with that key. A snippet is Replaced if its key matches a previous snippet, but their signatures differ. A snippet is Modified if its key matches a previous snippet and their signatures match; in this case, no dependent snippets are impacted... The desire is that user data persist whenever possible.
As an author and educator, I'm excited about using JShell in my work. And for Java developers, JShell presents new possibilities in debugging and exploratory programming. At long last, the edit-compile-run-debug cycle is no longer a stumbling block for writing good Java code.