Command Palette

Search for a command to run...

PHASE 0Beginner Java 9+ ~27 min· topic 6 of 8

Topic 0.6

Try Java Instantly with JShell

In one line

JShell is Java's interactive playground, included in every JDK since Java 9. You type one line of Java, press Enter, and see the result at once, with no class, no main method and no compile step, which makes it the fastest way to test an idea or explore a library method.

Think of it like this

A calculator versus writing a letter. To try one sum, you don't write a letter, post it and wait for a reply; you tap it into a calculator and see the answer straight away. Writing Main.java, compiling and running is the letter. JShell is the calculator: type a line, press Enter, see the answer.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

JShell
The interactive Java tool in the JDK. Type Java one line at a time and see results at once.
REPL
Read-Evaluate-Print Loop: a tool that reads a line, runs it, prints the result and waits for the next.
Expression
A piece of code that produces a value, such as 2 + 3 or "hi".length().
Declaration
Code that creates a named thing: a variable (int x = 5), a method or a class.
Snippet
One piece of code you type into JShell, such as one expression or one method.
Scratch variable
A name like $1 that JShell gives the result of an expression you didn't name.
Command
A JShell instruction starting with /, such as /vars or /exit. Not part of the Java language.
Tab completion
Pressing Tab to let the tool finish a name for you or list the choices.

Step by step

01Start JShell and do some sums

Open a terminal and type jshell. After the welcome message you get the jshell> prompt. Type an expression and press Enter. The answer comes back immediately, stored in a scratch variable such as $1.

x ==> 5 means "the variable x now holds 5". $2 ==> 10 means "the answer was 10, and I saved it as $2".

terminal
$ jshell
── expected output ──
| Welcome to JShell -- Version 21.0.9
| For an introduction type: /help intro
 
jshell> int x = 5
x ==> 5
 
jshell> x * 2
$2 ==> 10
 
jshell> "hi".toUpperCase()
$3 ==> "HI"
 
jshell> Math.max(3, 9)
$4 ==> 9

02Errors are instant and harmless

Make a mistake and JShell shows the same kind of message javac would, pointing at the problem with ^-----^. Nothing else is lost: your earlier variables are still there.

Exceptions while running are also shown and then forgotten. Notice the at (#4:1): snippet 4, line 1. That is JShell's version of a stack trace (Topic 0.7).

terminal
$ jshell> int y = "hello"
jshell> 10 / 0
── expected output ──
| Error:
| incompatible types: java.lang.String cannot be converted to int
| int y = "hello";
| ^-----^
 
| Exception java.lang.ArithmeticException: / by zero
| at (#4:1)

03Define methods and records

You can declare methods and types right at the prompt. JShell confirms with created method or created record. Then call them like any other code.

This is a quick way to test a small method before putting it in a real program: write it, try a few inputs, fix it, and copy the final version into your .java file.

terminal
$ jshell> int twice(int n) { return n * 2; }
jshell> twice(21)
jshell> record Pet(String name) {}
jshell> new Pet("Milo")
── expected output ──
| created method twice(int)
$10 ==> 42
| created record Pet
$12 ==> Pet[name=Milo]

04Explore arrays and the library

JShell prints values in a readable way, even arrays, which a normal println shows as gibberish such as [I@1b6d3586. That makes it handy for exploring what a method does to your data.

Here Arrays works without an import because JShell imports java.util.* and a few other packages at start-up. /imports lists them.

terminal
$ jshell> int[] nums = {3, 1, 2}
jshell> Arrays.sort(nums)
jshell> nums
── expected output ──
nums ==> int[3] { 3, 1, 2 }
nums ==> int[3] { 1, 2, 3 }

05The slash commands

Commands start with / and control JShell itself. The ones you'll use most are /vars, /methods, /list, /imports, /reset, /save, /open, /help and /exit.

/save mywork.jsh writes what you typed to a file, and /open mywork.jsh (or starting with jshell mywork.jsh) replays it later.

terminal
$ jshell> /vars
jshell> /imports
── expected output ──
| String x = "five"
| int $3 = 4
| int[] nums = int[3] { 1, 2, 3 }
| long big = 1099511627776
 
| 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.*

06Where JShell is looser than real Java

Redeclaring a variable replaces it, even with a different type: int x = 5 then String x = "five" is fine in JShell but an error in a method. Forward references are allowed: you can define a method that uses a variable you'll create later; JShell says the method "cannot be invoked until" that variable exists.

Checked exceptions (Topic 7.3) don't need handling at the top level: Thread.sleep(10) just works. In a real method, the compiler would insist on throws or try. Keep these differences in mind when you copy code from JShell into a program.

terminal
$ jshell> void hi() { System.out.println("hi " + name); }
jshell> String name = "Ben"
jshell> hi()
── expected output ──
| created method hi(), however, it cannot be invoked until variable name is declared
name ==> "Ben"
hi Ben

07JShell vs a real program

JShell is for trying things. Programs that you keep, share, test and run again belong in .java files. A good habit: experiment in JShell, then write the program.

The runnable examples in this topic are the same experiments written as normal programs, so you can run them with the Run button and compare.

JShell vs a real programdiagram
Rendering diagram…

Try it yourself

  1. 1

    Your first JShell session

    Start jshell, then type 7 * 6, "banana".length() and Math.sqrt(2). Predict each result before pressing Enter. Then type /vars to see the scratch variables JShell created, and /exit to leave.

    terminal
    $ jshell> 7 * 6
    jshell> "banana".length()
    jshell> Math.sqrt(2)
    ── expected output ──
    $1 ==> 42
    $2 ==> 6
    $3 ==> 1.4142135623730951
  2. 2

    Explore String with Tab

    Type "Hello". and press Tab. JShell lists every method you can call on a String. Pick repeat(, press Tab again to see its documentation, then finish "Hello".repeat(3).

    terminal
    $ jshell> "Hello".repeat(3)
    ── expected output ──
    $4 ==> "HelloHelloHello"
  3. 3

    Save and replay

    Define a variable and a method, then /save mywork.jsh and /exit. Start again with jshell mywork.jsh, and /list shows your snippets are back.

Code & diagrams

The JShell session as a program New tab

In a program you name everything yourself and print explicitly. JShell does both for you.

Sign in to run this example in your browser.

Expected output

x = 5
x * 2 = 10
upper: HI
max: 9
length of five: 4
Methods and records, tested in JShell, kept in a file Java 16+ New tab

In a file, methods called from main must be static (Topic 4.6), and the record sits beside the class.

Sign in to run this example in your browser.

Expected output

twice(21) = 42
twice(-4) = -8
A pet: Pet[name=Milo]
Printing arrays like JShell does New tab

println on an array prints its type and an identity code. Arrays.toString gives readable output, similar to JShell's display.

Sign in to run this example in your browser.

Expected output

Before: [3, 1, 2]
After:  [1, 2, 3]
Length: 3
A saved JShell script (mywork.jsh) Java 9+java

Run it with `jshell mywork.jsh`. Snippets need no class or main. /exit at the end closes JShell when the script finishes.

int price = 40
int count = 3
System.out.println("Total: " + price * count)
String shout(String s) { return s.toUpperCase() + "!"; }
System.out.println(shout("done"))
/exit

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Wrong type at the prompt

In JShell, type int y = "hello".

terminal
$ jshell> int y = "hello"
── what you'll see ──
| Error:
| incompatible types: java.lang.String cannot be converted to int
| int y = "hello";
| ^-----^

Break #2

Expect state after /reset

Declare int x = 5, run /reset, then type x.

terminal
$ jshell> /reset
jshell> x
── what you'll see ──
| Resetting state.
| Error:
| cannot find symbol
| symbol: variable x
| x
| ^

Myth vs fact

Myth

JShell runs a different, simplified Java.

Fact

It uses the real compiler and a real JVM. Each snippet is compiled to bytecode and run, so results match a normal program. Only a few rules are relaxed at the top level (redeclaration, forward references, checked exceptions).

Myth

Code that works in JShell will compile unchanged in a class.

Fact

Not always. Missing semicolons, redeclared variables, unhandled checked exceptions and relying on JShell's automatic imports all need fixing in a real .java file.

Myth

JShell is only for beginners.

Fact

Experienced developers use it to check API behaviour, test regular expressions, try date formats or inspect how a library behaves, faster than writing a test.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Each snippet is wrapped in a synthetic class and compiled with the real javac. By default the code runs in a separate JVM controlled through JDI (the debugger interface), so an infinite loop can be interrupted with Ctrl+C without killing JShell; --execution local runs it in the same JVM instead.

  • ▸

    Redefinition works because JShell tracks dependencies between snippets: when you redefine a method or type, dependent snippets are recompiled. Changing a variable's type replaces the variable and its value.

  • ▸

    Start-up scripts: jshell --startup DEFAULT is the normal set of imports, JAVASE imports every Java SE package, and PRINTING adds shorthand print/println methods. Use --class-path to load your project's jars and try your own classes interactively, and --enable-preview to try preview features.

  • ▸

    JShell is also a library (jdk.jshell module): IDE consoles and notebook tools build on its API (JShell.create(), eval(...)), which is how they evaluate Java snippets with real compiler diagnostics.

Remember this

  1. 1

    JShell is a REPL: it Reads what you type, Evaluates it, Prints the result and Loops back for more. Start it by typing jshell in a terminal. The prompt changes to jshell>. Leave with /exit.

  2. 2

    You can type expressions (anything that produces a value, like 2 + 3), declarations (variables, methods, classes, records) and statements (loops, ifs). The semicolon at the end of a single line is optional, and you don't need a class or main.

  3. 3

    When you type an expression without naming it, JShell stores the answer in a scratch variable called $ plus a number ($1, $2...). You can use those names in later lines. Variables you name yourself are shown as name ==> value.

  4. 4

    Lines starting with / are commands to JShell itself, not Java: /vars lists your variables, /methods your methods, /list everything you typed, /imports the active imports, /reset starts fresh, /save file.jsh and /open file.jsh save and load a session, /help explains everything.

  5. 5

    JShell is forgiving where a real program is strict. You can redeclare a variable with a new type, define a method that uses a variable you haven't declared yet, and call methods that throw checked exceptions without try/catch. Common packages such as java.util and java.util.stream are imported for you. That makes it great for experiments, and the reason you still write real programs for real work.

  6. 6

    Press Tab to complete names: type "hello". then Tab to list every String method. Press Tab again after an opening bracket to see a method's documentation. This turns JShell into a way to explore the standard library without leaving the terminal.

Explain it without notes

01

What is a REPL, and how does JShell fit that description?

02

What do x ==> 5 and $2 ==> 10 mean in JShell output?

03

Name three ways JShell is more relaxed than a normal Java source file.

04

When would you use JShell, and when would you write a .java file instead?

Practice

01

In JShell, compute how many seconds are in a week. Then write the same as a program.

02

In JShell, define a method square(int n) and call it with 7 and -3. Then write a program with the same method.

03

Use JShell to find what " Java ".strip() and " Java ".length() return. Write a program that prints both.

Trade-offs

  • ↔

    JShell gives instant feedback but its relaxed rules can hide problems a real compile would catch. Move code into a .java file as soon as it matters.

  • ↔

    JShell scripts (.jsh) are handy for quick automation, but for anything shared or long-lived, a normal program (or java Script.java) is clearer and fully checked.

Done when you can

  • Done when you can start JShell, evaluate expressions and leave with /exit.

  • Done when you can read name ==> value and $n ==> value output.

  • Done when you can define and call a method in JShell.

  • Done when you can use /vars, /list, /imports, /reset, /save and /open.

  • Done when you can explain how JShell's rules differ from a normal source file.