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.
$ jshell
| Welcome to JShell -- Version 25.0.4.1
| For an introduction type: /help intro
jshell>declare a variable, no class, no main. jshell echoes every value as name ==> value.
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:
forloops,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> 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.
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:
| command | does |
|---|---|
/vars | every variable, with its type and value |
/methods | every method you've defined |
/list | every snippet so far, numbered (/list -all includes the startup ones) |
/edit 5 | opens snippet 5 in an editor. save and it's re-run |
/save demo.jsh | writes your snippets to a file. /open demo.jsh loads them back |
/imports | what's imported. since java 25 that's all of java.base |
/reset | forget everything, start clean |
/exit | leave (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.
jshell or a file?
| reach for | when |
|---|---|
| jshell | "what does this return?", "does this compile?", exploring an API, checking an edge case like Integer.MAX_VALUE + 1 |
java Main.java | anything 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.
java Main.java pays its compile on every single run.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.