This is the first in a series of articles looking at some of the JDK Enhancement Proposals (JEPS) hoping to make their way into Java 9.

This week we’re going to look at JShell, otherwise knows as JEP 222. This was outlined in the JavaOne 2016 keynote with Mark Reinhold.

Finally, a REPL

REPLs, Read-Eval-Print Loops, are essential tools for immediate feedback. They have existed in other languages (such as Ruby’s IRB) for a long time. Hopefully, in Java 9, we will finally have a REPL for Java.

REPLs create an environment for you to evaluate code snippets such as declarations, statements and expressions. You should be able to test Java code as you write, which is useful when you’re trying to remember how to do something, or exploring the language.

The REPL functionality for the Java platform will be provided by JShell. It is the result of academic feedback, reacting to the trend of schools adopting languages with REPL functionality. If you are new to the language, it is a much quicker route to “Hello World”. JShell is an interactive tool that uses the Compiler API to take expressions, evaluate them in real time, compile them to bytecode, run them and return the results.

Getting started

The early access release of JDK 9 can be downloaded from here. This article uses version 9 Build 138.

Install JDK 9, and navigate to jdk-9.jdk/Contents/Home/.
Run the following command:

> bin/jshell -v
| Welcome to JShell -- Version 9-ea
| For an introduction type: /help intro

Let’s have a look at the intro.

jshell> /help intro
|
| intro
|
| The jshell tool allows you to execute Java code, getting immediate results.
| You can enter a Java definition (variable, method, class, etc), like: int x = 8
| or a Java expression, like: x + x
| or a Java statement or import.
| These little chunks of Java code are called 'snippets'.
|
| There are also jshell commands that allow you to understand and
| control what you are doing, like: /list
|
| For a list of commands: /help

Simple expressions

When evaluating a simple expression, such as the one below, JShell creates a temporary variable. It also tells us what the variable type is. Here it is $1.

jshell> 3 + 3
$1 ==> 6
| created scratch variable $1 : int

This gives us context and allows us to refer to past expressions, for example:

jshell> $1*6
$2 ==> 36
| created scratch variable $2 : int

You may have noticed that I’ve disposed of semicolons. That’s because although all input must be valid Java code, JShell will automatically provide the surrounding context.
To keep track of the variables, type in /vars.

jshell> /vars
| int $1 = 6
| int $2 = 36

There are no suprises with simple expressions. For example, one or both of the two operands needs to be a floating point value to result in a double.

jshell> 3.0/6.0
$3 ==> 0.5
| created scratch variable $3 : double

You can also explicitly create variables:

jshell> double myNumber = 1
myNumber ==> 1.0
| created variable myNumber : double

And perform basic operations:

jshell> for (int i=0; i<2; i++)
...> System.out.println("Looping")
Looping
Looping

Classes

Statements and expressions don’t have to be within a method, and variables don’t have to be declared or occur within a class. Equally methods can be written outside classes and interfaces. In the JEP this is explained as being “to facilitate rapid investigation and coding”, and it does.

However you can define a class should you wish, for example:

jshell> class Example {
...> int x;
...> int y;
...> public Example(int x, int y) {
...> this.x = x;
...> this.y = y;
...> }
...> public int getX() {
...> return x;
...> }
...> public int getY() {
...> return y;
...> }
...> }
| created class Example

You can then create objects:

jshell> Example eg = new Example(1,2);
eg ==> Example@3159c4b8
| created variable eg : Example

And call methods on them:

jshell> eg.getX();
$5 ==> 1
| created scratch variable $5 : int

Exploring APIs

JShell can also be used to explore APIs. For example, the String API.

jshell> String hello = "hello"
hello ==> "hello"
| created variable hello : String

Using tab completion, we can see the methods available:

jshell> hello.
charAt( chars() codePointAt( codePointBefore( codePointCount(
codePoints() compareTo( compareToIgnoreCase( concat( contains(
contentEquals( endsWith( equals( equalsIgnoreCase( getBytes(
getChars( getClass() hashCode() indexOf( intern()
isEmpty() lastIndexOf( length() matches( notify()
notifyAll() offsetByCodePoints( regionMatches( replace( replaceAll(
replaceFirst( split( startsWith( subSequence( substring(
toCharArray() toLowerCase( toString() toUpperCase( trim()
wait(

By pressing up, you can see previous snippets to check what was input before.

Creating methods

You can create methods:

jshell> String sayMyName(String name){
...> return "Your name is " + name;
...> }
| created method sayMyName(String)

And call them:

jshell> sayMyName("voxxed")
$4 ==> "Your name is voxxed"
| created scratch variable $4 : String

To check the methods you’ve created, type /methods

jshell> /methods
| printf (String,Object...)void
| sayMyName (String)String

Imports

You can see what packages are imported in JShell by typing /imports.

If you need to import another package, like Streams, import it as you would at the top of a Java class:

jshell> import java.util.stream.*

Now, say I have an array list of names:

jshell> voxxedNames
voxxedNames ==> [Mark, Katharine, Stephan]
| value of voxxedNames : ArrayList<String>

We can now perform more complex operations using streams, like looking for all of the entries which contain the letter “e” and outputting to a list:

jshell> voxxedNames.stream().filter(s -> s.contains("e")).collect(Collectors.toList())
$5 ==> [Katharine, Stephan]
| created scratch variable $5 : List<String>

Other useful commands

JShell allows you to save snippets to a source file. It is also possible to open files as source input, see history and reset JShell. Out of scope for JEP 222 are graphical interfaces, debugger support, and IDE-like functionality.

It should be a great asset to IDEs, allowing you to test snippets of Java and then insert them into code. As soon as you start using it, you’ll wonder how you went without.

When you are finished, just type:

jshell> /exit
| Goodbye

 

Next up: HTTP/2 Client

Java 9 series: JShell

| Java Language| 1,304 views |
About The Author
- Katharine is a Java developer by trade, turned Community & Content Manager for Voxxed. Helping developers learn and share knowledge. Contact me at kbe@voxxed.com with any news, articles or tutorials.