Code Pumpkin

JShell: The Java Shell and REPL | Java9

April 17, 2017
Posted by Abhi Andhariya

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.

JShell Edit Pad


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


    Surviving Java Developer, Passionate Blogger, Table Tennis Lover, Bookworm, Occasional illustrator and a big fan of Joey Tribbiani, The Walking Dead and Game of Thrones...!!



    Tags: ,


    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.
    Total Posts : 124
    follow us in feedly

    Like Us On Facebook