Experimenting with JShell

Experimenting with JShell: Testing out Java code snippets without writing a program

Starting with Java 9, the JDK includes JShell a Read-Evaluate-Print Loop (REPL) that runs from the command line.  JShell allows a developer to run “snippets” of code without going through the whole cycle of writing a program, making sure it compiles and then running it.  It allows a user to quickly experiment with new features.  JShell also allows you to attach to an external library, so it can also be used for trying out a new library.

Prerequisites

  • JDK 9 or Higher

Getting Started

In order to use JShell, you need a JDK 9 or higher.  I downloaded and installed JDK 10.  I did not add Java 10 to my path, so I need to be explicit about where I’m calling JShell.

Open a command window and if you’ve got JDK 9 or higher in your path, type jshell or include the path to JDK 9 or 10 bin.

>"java-home\bin\jshell"
| Welcome to JShell -- Version 10.0.1
| For an introduction type: /help intro

jshell>

To exit JShell enter “/exit” at the jshell prompt.

jshell> /exit
| Goodbye

Hello World Two Ways

Let’s take the classic Hello World example to illustrate the contrast.  To write a HelloWorld example program, we start with a blank HelloWorld.java file.  After opening the file in a text editor (I like jEdit), we declare the HelloWorld class and then make it a main class by creating a main method.  We end up with something like this.

public class HelloWorld { 
   public static void main(String[] args) {    
      System.out.println("Hello World!"); 
   }
}

The next step is to compile the project.  Let’s pretend I forgot my semicolon.

>javac HelloWorld.java
HelloWorld.java:3: error: ';' expected
 System.out.println("Hello World!")
 ^
1 error

After I workout my compile errors, I get a clean compile and I run it.

>javac HelloWorld.java

>java HelloWorld
Hello World!

To use JShell, you do the following.

>"java-home\bin\jshell"
| Welcome to JShell -- Version 10.0.1
| For an introduction type: /help intro

jshell> System.out.println("Hello World");
Hello World

jshell>

Snippets and Variables

JShell keeps track of the code in snippets.  The /list command can be used to list the snippets and they can then be referenced to rerun or save to an external file.  If we run a series of operations and then enter /list, we get a numbered list. Each snippet is assigned an id.  A given snippet can then be rerun using /{id}.  E.g. /1 will rerun the first snippet below, the “Hello World” printing.  To rerun the last snippet, use /!.

jshell> System.out.println("Hello World");
Hello World

jshell> int ten = 10;
ten ==> 10

jshell> ten * 50;
$3 ==> 500

jshell> int x = $3/5;
x ==> 100

jshell> /list

 1 : System.out.println("Hello World");
 2 : int ten = 10;
 3 : ten * 50;
 4 : int x = $3/5;

jshell> /1
System.out.println("Hello World");
Hello World

jshell>

You can declare variables in JShell, but if you run an operation without placing it in an explicit variable, JShell creates one for you and tells you what it is (the $3 ==> 500 above is an example of this).  To list your variables, enter the /var command.  In the list, we see the “ten” and “x” variables that we explicitly defined and also the $3 variable that JShell created for us.

jshell> /var
| int ten = 10
| int $3 = 500
| int x = 100

Methods

To use methods in JShell, just define the method as usual.  JShell can handle using multiple lines, so there’s no need to try to define it all on one line.  Once defined the method can be called in the usual way.  To see a list of defined methods, use the /method command.

jshell> public String concatString(String first, String second) {
 ...> return first + second;
 ...> }
| created method concatString(String,String)

jshell> String newString = concatString("Bigger", "String");
newString ==> "BiggerString"

jshell> /method
| String concatString(String,String)

It’s possible to write methods that reference other variables.  If the method references a variable that doesn’t exist, it tells you that it created the method, but you can’t use it yet.  Once you declare the variable, you can call the method.  The below example references a list.  After we declare the list, we can use the method to add values to it.

jshell> public void addString(String toAdd) {
 ...> strlist.add(toAdd);
 ...> }
| created method addString(String), however, it cannot be invoked until variable strlist is declared

jshell> List strlist = new ArrayList();
strlist ==> []

jshell> addString("Hi");

jshell> addString("Hello");

jshell> addString("Hola");

jshell> strlist
strlist ==> [Hi, Hello, Hola]

Conclusion

JShell is a neat way to quickly experiment with bits of Java code.  I’ve seen it touted as a way to learn Java, but I’d argue that a lot of the learning of a language is how to set up your program, so I’m not sure how useful it is for that.  For a person completely new to programming, it may be an interesting way to introduce basic programming concepts e.g. variables, functions, etc.

JShell has more advanced features that I didn’t cover that would make it more useful to the experienced developer.  The ability to reference external code makes it a good way to play with third party libraries or to exercise a new library of your own.  JShell includes a way to write snippets to a file, so you can quickly save off examples of things that work or create scripts to quickly set up a future JShell session.

References

https://docs.oracle.com/javase/10/jshell/toc.htm