JShell: The Java Shell and REPL | Java9
In this article, we are going to understand one of most discussed feature of Java9 i.e. JShell. It was started as project Kulla and included in Java9 release.
You can download JDK 1.9 from here based on your OS Platform requirements.
Oracle Corporation is trying to integrate most of Scala Features into Java. They have already integrated some Functional Programming Features as part of Java SE 8.
Scala’s one of the best features is REPL (Read-Evaluate-Print-Loop). Its a command line interface and Scala Interpreter to execute Scala programs. It is very easy to use Scala REPL to learn basics for beginners. Oracle has planned to integrate that REPL feature in Java SE 9 as JShell.
If you are also interested in learning other features of Java9, you can read our post Java 9 Features
What is JShell?
JShell is command line tool to include REPL (Read-Eval-Print Loop) into Java programming language i.e.
Java + REPL = JShell
A Read-Eval-Print Loop (REPL) is an interactive programming tool which loops, continually reading user input, evaluating the input, and printing the value of the input or a description of the state change the input caused.
A program written in a REPL environment is executed piecewise.
It is useful to learn Java very easily. It does not require any IDEs or Editors to execute simple Java Programs. It is very useful for Beginners and Experts to use it to learn and evaluate new features.
Motivation behind including REPL in Java
Earlier in Java, if you want to print "Hello, world!", you need to create public class and public static main method to test it.
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.
Scala, Ruby, JavaScript, Haskell, Clojure, and Python all have REPLs and all allow small initial programs. JShell adds this REPL functionality to the Java platform.
How to Run JShell?
Once you will download jdk9, you will find jshell executable in a jdk bin directory. I suggest running it in verbose (-v
) mode for the first time:
C:\Users\codePumpkin>jshell -v | Welcome to JShell -- Version 9-ea | For an introduction type: /help intro jshell>
Default Imports
To know about “What are all the default imports are available in Java SE 9 REPL”, we need to use “/imports” command as shown below:
jshell> /imports | import java.io.* | import java.math.* | import java.net.* | import java.nio.file.* | import java.util.* | import java.util.concurrent.* | import java.util.function.* | import java.util.prefs.* | import java.util.regex.* | import java.util.stream.*
If we want to create or test any class or interface from these packages, then we don’t need any external import.
jshell> String str = new String("Code Pumpkin") str ==> "Code Pumpkin" | created variable str : String
Here java.lang.* package is not listed in the above packages list. But as it is default package, we can use its String class without any external imports.
External Imports
However, if we want to test any other package related class or interface, then we need to use external import. Otherwise we will get error as shown in the below code snippet:
jshell> ByteBuffer buf = ByteBuffer.allocate(48); | Error: | cannot find symbol | symbol: class ByteBuffer | ByteBuffer buf = ByteBuffer.allocate(48); | ^--------^ | Error: | cannot find symbol | symbol: variable ByteBuffer | ByteBuffer buf = ByteBuffer.allocate(48); | ^--------^
We need to use import statement to import that whole package or specific class as shown below:
jshell> import java.nio.ByteBuffer jshell> ByteBuffer buf = ByteBuffer.allocate(48); buf ==> java.nio.HeapByteBuffer[pos=0 lim=48 cap=48] | created variable buf : ByteBuffer
Expressions
You can type any valid java expression, and it will tell you the returned value, it’s type and assign it to a default variable i.e. $1, $2…
jshell> 10 + 5 $1 ==> 15 | created scratch variable $1 : int jshell> 10 - 5 $2 ==> 5 | created scratch variable $2 : int jshell> $1 $1 ==> 15 | value of $1 : int jshell> $2 $2 ==> 5 | value of $2 : int
Variables
Java SE 9 assigns Internal variables like “$1, $2, $3” and so on for any unassigned results. You can check this in the above code snippet of Expression section.
Are these default variables immutable or mutable? lets try.
jshell> $1 = 100 $1 ==> 100 | assigned to $1 : int
It proves that they are mutable i.e. we can change their values.
We can also provide user-defined names to variable.
jshell> int a = 10 a ==> 10 | created variable a : int
Methods
We can also define methods and even replace them:
jshell> void helloJShell() { System.out.println("hello JShell"); } | created method helloJShell() jshell> helloJShell(); hello JShell jshell> void helloJShell() { System.out.println("wow, I replaced a method"); } | modified method helloJShell() | update overwrote method helloJShell() jshell> helloJShell() wow, I replaced a method
Commands
Aparat from language syntax we can execute jshell commands. Some of the most useful ones (/help to list all of them) are:
Listing variables
jshell> /vars | int x = 0 | double j = 0.5
Listing methods
jshell> /methods | helloJShell ()void
Listing sources
jshell> /list 1 : 10 + 5 2 : 10 - 5 3 : 10 / 5 4 : 10 * 5 5 : $1 6 : $2 7 : $1 = 100 8 : int a = 10 9 : helloJShell(); 10 : void helloJShell() { System.out.println("wow, I replaced a method"); } 11 : helloJShell()
Editing sources in external editor
jshell> /edit helloJShell
Opens external editor (JShell Editor), and allows to edit and replaces helloJShell method as shown in below image.
Exiting JShell
jshell> /exit | Goodbye
we can also use Ctrl + D command to exit from JShell tool.
Other JShell Features
- We can see the history of our previous commands.
- It supports Tab-Completion feature.
- It adds semicolons automatically so we don’t need to use them.
Example Use Cases
After 20 years of Java without REPL, one might wonder what all scenarios are suitable for JShell. Here are some examples.
1. Veryfing return type
Remember the time we learned that dividing two integers in Java does not result in floating number? For some time I was convinced that both numerator and denominator have to be floating for a result to be floating too. Let’s test that
jshell> 1/2 $1 ==> 0 | created scratch variable $1 : int jshell> 1.0/2 $2 ==> 0.5 | created scratch variable $2 : double jshell> 1/2.0 $3 ==> 0.5 | created scratch variable $3 : double jshell> 1.0f/2 $4 ==> 0.5 | created scratch variable $4 : float jshell> 1/2.0f $5 ==> 0.5 | created scratch variable $5 : float
Turns out only one of them has to be floating.
2. Formatting
Sometimes the logs need to be verbose and properly formatted. This is tedious task and usually leads to few recompile cycles which significantly slows us down. Imagine you forgot what was the format sign responsible for integers. You can quickly verify that.
Let’s try %i
(integer):
jshell> printf("I got %i apple",1) | java.util.UnknownFormatConversionException thrown: Conversion = 'i' | at Formatter$FormatSpecifier.conversion (Formatter.java:2691) | at Formatter$FormatSpecifier.<init> (Formatter.java:2717) | at Formatter.parse (Formatter.java:2565) | at Formatter.format (Formatter.java:2507) | at PrintStream.format (PrintStream.java:977) | at PrintStream.printf (PrintStream.java:873) | at printf (#s8:1) | at (#51:1)
Oops, maybe %d
(decimal) :
jshell> printf("I got %d apple",1) I got 1 apple
That's all for this topic. If you guys have any suggestions or queries, feel free to drop a comment. We would be happy to add that in our post. You can also contribute your articles by creating contributor account here.
Happy Learning 🙂
If you like the content on CodePumpkin and if you wish to do something for the community and the planet Earth, you can donate to our campaign for planting more trees at CodePumpkin Cauvery Calling Campaign.
We may not get time to plant a tree, but we can definitely donate ₹42 per Tree.
About the Author
Comments and Queries
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:<pre><code class="java"> String foo = "bar"; </code></pre>For more information on supported HTML tags in disqus comment, click here.