Exploring JShell
Introduction
JShell
is REPL (Read, Eval, Print, Loop) for Java Programming Language,
introduced in Java 9. It’s a great way to quickly prototype an idea or learn
some new API. The great thing about JShell
is it comes with builtin code
completion and documentation. Exploring new API or Java library have never been
to easy!
Start and Exit JShell
If you have Java 9+ installed on your machine JShell
is already installed. To
start the JShell
type following command, assuming $JAVA_HOME/bin
is in
$PATH
:
$ jshell -version
jshell 16.0.1
$ jshell
| Welcome to JShell -- Version 16.0.1
| For an introduction type: /help intro
jshell> /exit
| Goodbye
You can type any statement or expression in JShell
. Control commands start
with /
. Typing /exit
or pressing Ctrl+d
will exit out of JShell
.
Getting Help
JShell has a great help
support. Help can be accessed with /help
or /?
. If
you enter /help
command then list of all commands will be printed. /help
can be
called for other commands or subjects. Subjects are detailed text on some
specific topic. Currently available subjects are intro
, keys
, id
,
shortcuts
, context
, rerun
.
jshell> /help
| Type a Java language expression, statement, or declaration.
| Or type one of the following commands:
| /list [<name or id>|-all|-start]
| list the source you have typed
| /edit <name or id>
# ... (Showing first 5 lines)
jshell> /help /list
|
| /list
| =====
|
| Show the snippets, prefaced with their snippet IDs.
|
| /list
| List the currently active snippets of code that you typed or read with /open
|
| /list -start
# ... (Showing first 10 lines)
jshell> /help intro
|
| intro
| =====
|
| The jshell tool allows you to execute Java code, getting immediate results.
# ... (Showing first 5 lines)
Playing with JShell
You can write any statement, declare methods, class in JShell
. Each of these
statements are called snippets.
jshell> Math.PI
$1 ==> 3.141592653589793
jshell> 3 + 8
$2 ==> 11
jshell> int i = 20;
i ==> 20
jshell> int square(int x) {
...> return x * x;
...> }
| created method square(int)
jshell> class Person {
...> private String name;
...>
...> public Person(String name) {
...> this.name = name;
...> }
...>
...> @Override
...> public String toString() {
...> return "Person{name=" + name + "}";
...> }
...> }
| created class Person
jshell> nothing
| Error:
| cannot find symbol
| symbol: variable nothing
| nothing
| ^-----^
jshell> square($2)
$6 ==> 121
jshell> square(i)
$7 ==> 400
jshell> /2
3 + 8
$8 ==> 11
You can also rerun last snippet with /!
and -<n>
to rerun n-th previous snippet.
You can view snippets using /list
command. By default it only shows active
snippets, -all
options shows all deleted, startup and error snippets. Error
snippets are prefixed with e
and startup snippets are prefixed with s
.
jshell> /list -all
s1 : import java.io.*;
s2 : import java.math.*;
s3 : import java.net.*;
s4 : import java.nio.file.*;
s5 : import java.util.*;
s6 : import java.util.concurrent.*;
s7 : import java.util.function.*;
s8 : import java.util.prefs.*;
s9 : import java.util.regex.*;
s10 : import java.util.stream.*;
1 : Math.PI
2 : 3 + 8
3 : int i = 20;
4 : int square(int x) {
return x * x;
}
5 : class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{name=" + name + "}";
}
}
6 : square($2) // Can use custom variable
e1 : nothing
7 : square(i)
8 : 3 + 8
You can also list variables, methods, classes and imports using /vars
,
/methods
, /types
, /imports
respectively.
jshell> /vars
| double $1 = 3.141592653589793
| int $2 = 11
| int i = 20
jshell> /methods
| int square(int)
jshell> /types
| class Person
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.*
These packages are imported by default.
A snippets can be dropped or edited using /drop
and /edit
command. Dropped snippets can be seen using -all
in /list
command.
jshell> /drop 6
| dropped variable $6
jshell> /set editor vim
| Editor set to: vim
jshell> /edit 4
# Opened in Vim, making square to cube and saving it.
# (In Vim)
# int square(int x) {
# return x * x;
# }
# New method snippet is created cube() as $8
jshell> /methods
| int square(int)
| int cube(int)
jshell> /list 8
8 : int cube(int x) {
return x * x * x;
}
By default /edit
command searches in $JSHELLEDITOR
, $VISUAL
, $EDITOR
in
this order. Otherwise opens in a simple AWT editor.
Saving and Loading File
You can save and load JShell
session data with /save
and /open
command:
jshell> /save article.jsh
jshell> /exit
$ jshell
# /open command can also open java file ie '/open Person.java'
jshell> /open article.jsh
jshell> /list
# Same output as previous
History
You can view entered commands using /history
command. -all
will display
commands of all previous sessions. If we run /history
command after previous
commands following output will be displayed:
jshell> /history
/open article.jsh
/list
/history
AutoComplete & Documentation
JShell
has builtin autocomplete and documentation support.
jshell> Sy<Tab>
SyncFailedException SynchronousQueue System
jshell> Sys<Tab> # will autocomplete 'System'
jshell> System.out.p<Tab> # out.p becomes out.print
print( printf( println(
jshell> System.out.println(<Tab>
$1 $2 i square(
Signatures:
void PrintStream.println()
void PrintStream.println(boolean x)
void PrintStream.println(char x)
void PrintStream.println(int x)
void PrintStream.println(long x)
void PrintStream.println(float x)
void PrintStream.println(double x)
void PrintStream.println(char[] x)
void PrintStream.println(String x)
void PrintStream.println(Object x)
<press tab again to see documentation>
It shows all candidate variables along with all overloaded methods. If <Tab>
is
pressed again shows documentation.
jshell> System.out.println(
void PrintStream.println()
Terminates the current line by writing the line separator string.The line separator string is
defined by the system property line.separator , and is not necessarily a single newline
character ( '\n' ).
<press tab to see next documentation>
jshell> System.out.println(
Forward Reference
JShell
can define method or class with previously declared or undeclared
variables. Lets see that in example:
jshell> int ten = 10
ten ==> 10
jshell> int add10(int x) {
...> return x + ten;
...> }
| created method add10(int)
jshell> add10(5)
$3 ==> 15
jshell> int add20(int y) {
...> return y + twenty;
...> }
| created method add20(int), however, it cannot be invoked until variable twenty is declared
jshell> add20(7)
| attempted to call method add20(int) which cannot be invoked until variable twenty is declared
jshell> twenty = 20
| Error:
| cannot find symbol
| symbol: variable twenty
| twenty = 20
| ^----^
jshell> int twenty = 20
twenty ==> 20
jshell> add20(7)
$7 ==> 27
Keyboard Shortcuts
Following are some important shortcuts to remember. For all keyboard shortcuts
see /help keys
.
Shortcut | Description |
---|---|
Ctrl+L |
Clear Screen |
Ctrl+C |
Interrupt Statement |
Ctrl+A |
Beginning of line |
Ctrl+E |
End of line |
Ctrl+R |
Reverse Search |
Ctrl+Enter |
Insert new line in snippet |
Ctrl+_ |
Undo edit |
Ctrl+X then Ctrl+B |
Navigate to matching bracket |
Meta+U |
Uppercase word |
Meta+L |
Lowercase word |
JShell
also have some code helper shortcuts.
Shortcut | Description |
---|---|
Shift+Tab then v |
Declare variable for expression |
Shift+Tab then m |
Declare method for expression |
Shift+Tab then i |
Automatically import expression class |
Context & Environment
Execution environment can be updated with /evn
, /reset
, /reload
commands.
With /env
command external module or library can be loaded. Lets load apache
common in JShell
.
$ wget https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar
$ jshell --class-path commons-lang3-3.12.0.jar
# Alternative
# jshell> /env -class-path commons-lang3-3.12.0.jar
jshell> /env
| --class-path commons-lang3-3.12.0.jar
jshell> import org.apache.commons.lang3.StringUtils
jshell> StringUtils.abbreviate("Hello World", 10)
$2 ==> "Hello W..."
jshell> /list
1 : import org.apache.commons.lang3.StringUtils;
2 : StringUtils.abbreviate("Hello World", 10)
# /reset will restart the context and reset all entered snippets
jshell> /reset
| Resetting state.
jshell> /list # Prints Nothing
jshell> 2 + 2
$1 ==> 4
# /reload will restart the context and rerun entered snippets
jshell> /reload
| Restarting and restoring state.
-: 2 + 2
jshell> /list
1 : 2 + 2
/set Command
With /set
command various options like editor, startup snippets, displayed
feedback, prompt, snippets indent number can be configured. Running only /set
will display configs:
jshell> /set
| /set editor -default
| /set indent 4
| /set start -retain -default
| /set feedback normal
|
| Available feedback modes:
| concise
| normal
| silent
| verbose
|
| To show mode settings use '/set prompt', '/set truncation', ...
| or use '/set mode' followed by the feedback mode name.
JShell has a startup script PRINTING
which can be used to import print
helpers. -retain
option will retain configuration for future JShell
sessions:
jshell> /set start -retain DEFAULT PRINTING
jshell> /list -all
s1 : void print(boolean b) { System.out.print(b); }
s2 : void print(char c) { System.out.print(c); }
s3 : void print(int i) { System.out.print(i); }
s4 : void print(long l) { System.out.print(l); }
s5 : void print(float f) { System.out.print(f); }
s6 : void print(double d) { System.out.print(d); }
s7 : void print(char s[]) { System.out.print(s); }
s8 : void print(String s) { System.out.print(s); }
s9 : void print(Object obj) { System.out.print(obj); }
s10 : void println() { System.out.println(); }
s11 : void println(boolean b) { System.out.println(b); }
s12 : void println(char c) { System.out.println(c); }
s13 : void println(int i) { System.out.println(i); }
s14 : void println(long l) { System.out.println(l); }
s15 : void println(float f) { System.out.println(f); }
s16 : void println(double d) { System.out.println(d); }
s17 : void println(char s[]) { System.out.println(s); }
s18 : void println(String s) { System.out.println(s); }
s19 : void println(Object obj) { System.out.println(obj); }
s20 : void printf(java.util.Locale l, String format, Object... args) { System.out.printf(l, format, args); }
s21 : void printf(String format, Object... args) { System.out.printf(format, args); }
s22 : import java.io.*;
s23 : import java.math.*;
s24 : import java.net.*;
s25 : import java.nio.file.*;
s26 : import java.util.*;
s27 : import java.util.concurrent.*;
s28 : import java.util.function.*;
s29 : import java.util.prefs.*;
s30 : import java.util.regex.*;
s31 : import java.util.stream.*;
jshell> println("Hello World")
Hello World