skip to content

jshell

a REPL for java. the fastest way to try anything on this site.

chapter
chapter 01.05
reading time
6 min read

jshell is java's REPL: type a line of java, press enter, see the result. no file, no class, no main, no compile step. it ships with every JDK since java 9, and it's the fastest way to try anything on this site.

the picture

writing a java file to test one expression is like mailing a letter to ask what time it is. jshell is just asking out loud.

REPL stands for read, eval, print, loop: it reads what you typed, evaluates it, prints the result, and loops back for more. variables and methods you define stick around until you quit, so you can build things up one line at a time.

terminal
$ jshell
|  Welcome to JShell -- Version 25.0.4.1
|  For an introduction type: /help intro
 
jshell>
jshelljdk 25.0.4.1
| Welcome to JShell -- Version 25.0.4.1
| For an introduction type: /help intro
jshell> int x = 5
x ==> 5
jshell>

declare a variable, no class, no main. jshell echoes every value as name ==> value.

step 1/11
press step to type the next snippet. every output is copied from a real jshell 25 session with these exact inputs. watch the $ numbers: they count snippets, and the failed one doesn't get one.

what you can type

pretty much any java you'd write inside a method, plus declarations:

  • expressions: 2 + 2, "abc".length(), List.of(1, 2). the result lands in a scratch variable like $5.
  • statements: for loops, ifs, System.out.println(...). statements that produce no value print nothing extra.
  • declarations: variables, methods, even whole classes and records. redeclare one and it's replaced.

semicolons are optional at the end of a line. multi-line code works too: jshell sees the open brace and waits, with a ...> prompt, until it's closed.

jshell
jshell> int[] a = {3, 1, 2}
a ==> int[3] { 3, 1, 2 }
 
jshell> Arrays.sort(a)
 
jshell> a
a ==> int[3] { 1, 2, 3 }

arrays print their contents (a plain println of an array would give you something like [I@1b6d3586, more on that in arrays). Arrays.sort returns nothing, so jshell prints nothing for it.

predict the output
text
jshell> String greet(String n) { return "hi " + n; }
jshell> String twice(String n) { return greet(n) + "!"; }
jshell> String greet(String n) { return "hey " + n; }
jshell> twice("duke")

the commands

anything starting with / talks to jshell itself, not to java. the ones you'll actually use:

commanddoes
/varsevery variable, with its type and value
/methodsevery method you've defined
/listevery snippet so far, numbered (/list -all includes the startup ones)
/edit 5opens snippet 5 in an editor. save and it's re-run
/save demo.jshwrites your snippets to a file. /open demo.jsh loads them back
/importswhat's imported. since java 25 that's all of java.base
/resetforget everything, start clean
/exitleave (or ctrl d)

and the two keys that make it fly: tab completes names and shows a method's overloads ("abc". then tab lists every String method), and ↑ brings back your previous lines.

what's actually happening

jshell isn't an interpreter for some java-like language. it's the real compiler and the real JVM, wired up so you don't see them.

hover a stage.

hover a stage. your snippets never run inside jshell itself: they run in a second JVM that jshell starts and talks to over a socket.

jshell or a file?

reach forwhen
jshell"what does this return?", "does this compile?", exploring an API, checking an edge case like Integer.MAX_VALUE + 1
java Main.javaanything you want to keep, anything longer than a screen, anything with input or real control flow

both are one command away, so the real rule is: if you're wondering, try it.

start jshell783 ms
first snippet100 ms
each snippet after15 ms
java Main.java, every run200 ms
medians of 7 runs on jdk 25, apple silicon. jshell pays once to start two JVMs and warm up the compiler, then answers fast. java Main.java pays its compile on every single run.
keylines
  • jshell = type java, see the result. no class, no main, no compile step.
  • unnamed results become scratch variables: $2, $3... and you can use them.
  • /vars, /methods, /list, /edit, /save. tab completes everything.
  • it's the real javac and a real (separate) JVM, so its answers are java's answers.
  • it's more forgiving than a file. moving code into a class may need imports, semicolons and try/catch.