JShell Basics

Su Suriya Ravichandran Updated 14 Nov 2026
7 min read ·Lesson 39 of 133

JShell is Java's interactive console, included in every JDK since Java 9. You type a Java expression, statement, or declaration, press Enter, and see the result immediately. There is no class to write, no main method, and no separate compile step. This kind of tool is called a REPL (Read–Evaluate–Print Loop), and it is the fastest way to test an idea, check how an API behaves, or learn a language feature.

Starting and Exiting

jshell
|  Welcome to JShell -- Version 25.0.1
|  For an introduction type: /help intro

jshell>

The jshell> prompt waits for input. To leave, type /exit or press Ctrl+D.

If the command is not found, the JDK's bin directory is not on your PATH (see the Install JDK lesson). JShell is part of the JDK; it is not included in JRE-only runtimes.

Evaluating Expressions

Type an expression and JShell prints its value:

jshell> 7 * 6
$1 ==> 42

jshell> "Java".toUpperCase()
$2 ==> "JAVA"

jshell> Math.sqrt(144)
$3 ==> 12.0

jshell> 10 / 4
$4 ==> 2

jshell> 10 / 4.0
$5 ==> 2.5

Each result is stored in an automatically created variable named $1, $2, and so on, which you can use later:

jshell> $1 + 8
$6 ==> 50

Semicolons are optional for a single expression or statement on a line. JShell adds them for you.

Declaring Variables

jshell> int count = 10
count ==> 10

jshell> String name = "Ada"
name ==> "Ada"

jshell> var prices = List.of(19.99, 5.49, 120.0)
prices ==> [19.99, 5.49, 120.0]

jshell> count * 3
$10 ==> 30

Variables persist for the whole session. Unlike in a normal program, you may redeclare a variable with a different type, which replaces the old one:

jshell> String count = "ten"
count ==> "ten"

This makes experimenting easy: there is no need to invent new names every time you change your mind.

Multi-Line Code

When a line is incomplete, JShell shows a continuation prompt ...> and waits:

jshell> for (int i = 1; i <= 3; i++) {
   ...>     System.out.println("Line " + i);
   ...> }
Line 1
Line 2
Line 3

JShell knows the statement is complete when the braces balance.

Defining Methods

Methods can be declared at the top level, outside any class:

jshell> int square(int n) {
   ...>     return n * n;
   ...> }
|  created method square(int)

jshell> square(9)
$12 ==> 81

A method may refer to something that does not exist yet. JShell creates it but marks it as unusable until the missing piece is defined:

jshell> double withTax(double amount) {
   ...>     return amount * (1 + TAX_RATE);
   ...> }
|  created method withTax(double), however, it cannot be invoked until variable TAX_RATE is declared

jshell> double TAX_RATE = 0.18
TAX_RATE ==> 0.18

jshell> withTax(100)
$15 ==> 118.0

This forward reference support lets you build up code in whatever order ideas occur to you.

Redefining a method with the same signature replaces it, so you can fix a bug and re-run immediately.

Defining Classes, Records, and Enums

jshell> record Product(String name, double price) {}
|  created record Product

jshell> var p = new Product("Keyboard", 49.99)
p ==> Product[name=Keyboard, price=49.99]

jshell> p.price() * 2
$18 ==> 99.98

jshell> enum Size { S, M, L }
|  created enum Size

jshell> Size.valueOf("M").ordinal()
$20 ==> 1

Classes and interfaces work the same way, which makes JShell useful for sketching a design before moving it into a project.

Default Imports

JShell starts with a set of commonly used packages already imported, including:

java.io.*        java.math.*         java.net.*
java.nio.file.*  java.util.*         java.util.concurrent.*
java.util.function.*  java.util.regex.*  java.util.stream.*

That is why List.of(...) worked above without an import. Other packages need an explicit import:

jshell> import java.time.*

jshell> LocalDate.now().plusDays(30)
$22 ==> 2026-12-10

/imports lists everything currently imported.

Exceptions and Errors

JShell reports errors without ending the session:

jshell> int x = "hello"
|  Error:
|  incompatible types: java.lang.String cannot be converted to int
|  int x = "hello";
|          ^-----^

jshell> List.of(1, 2, 3).get(5)
|  Exception java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3
|        at ImmutableCollections$ListN.get (ImmutableCollections.java:...)
|        at (#24:1)

Compile errors show the exact position. Runtime exceptions show a stack trace, where #24:1 means snippet 24, line 1.

A convenience specific to JShell: top-level statements may call methods that throw checked exceptions without a try/catch. In a normal program, the following would require handling IOException:

jshell> Files.readString(Path.of("notes.txt")).lines().count()
$25 ==> 12

JShell Commands

Lines starting with / are commands for JShell itself, not Java code:

CommandEffect
/helpList all commands; /help intro for a short tutorial
/varsList declared variables with their types and values
/methodsList declared methods
/typesList declared classes, interfaces, enums, and records
/importsList active imports
/listShow the snippets entered so far, with their IDs
/edit <name or id>Open a snippet in an editor window to modify it
/drop <name or id>Remove a snippet
/save file.jshSave the session's snippets to a file
/open file.jshLoad and run snippets from a file
/resetClear everything and start fresh
/historyShow everything typed this session
/exitQuit
jshell> /vars
|    int count = 10
|    String name = "Ada"
|    List<Double> prices = [19.99, 5.49, 120.0]
|    double TAX_RATE = 0.18

jshell> /methods
|    int square(int)
|    double withTax(double)

Commands can be abbreviated to any unique prefix, such as /v for /vars.

Tab Completion and Documentation

Press Tab to complete names and see available methods:

jshell> "hello".to<Tab>
toCharArray()   toLowerCase(   toString()   toUpperCase(

After an opening parenthesis, pressing Tab shows the method's signatures. Pressing Tab again shows its documentation:

jshell> "hello".substring(<Tab>
Signatures:
String String.substring(int beginIndex)
String String.substring(int beginIndex, int endIndex)

<press tab again to see documentation>

This makes JShell a quick reference for any class in the JDK.

Shift+Tab followed by v creates a variable from the expression you have typed; Shift+Tab followed by i offers to add an import for an unresolved type.

Feedback Modes

JShell's verbosity is adjustable:

jshell> /set feedback verbose     // describes every action in detail
jshell> /set feedback concise     // minimal output
jshell> /set feedback normal      // the default

Verbose mode shows the inferred types of results, which helps when learning:

jshell> /set feedback verbose
jshell> 10 / 4.0
$27 ==> 2.5
|  created scratch variable $27 : double

Using Libraries and Scripts

Add JARs to the class path when starting:

jshell --class-path lib/gson-2.11.0.jar
jshell> import com.google.gson.Gson
jshell> new Gson().toJson(Map.of("ok", true))
$2 ==> "{\"ok\":true}"

Within a session, /env --class-path <path> changes the class path.

A .jsh file holds snippets that can be run as a script:

// report.jsh
var scores = List.of(72, 88, 95, 61, 79);
System.out.println("Average: " + scores.stream().mapToInt(i -> i).average().orElse(0));
System.out.println("Highest: " + Collections.max(scores));
/exit
jshell report.jsh
Average: 79.0
Highest: 95

The final /exit makes JShell quit after running the script instead of staying open at the prompt.

When to Use JShell

Use JShell forUse a source file or project for
Checking how a method behaves on specific inputPrograms you will run again or share
Testing a regular expression or format stringCode with several interacting classes
Learning a new API or language featureAnything that needs tests or a build tool
Quick calculations and data explorationApplications with dependencies managed by Maven/Gradle

A productive habit is to keep JShell open while coding. When unsure exactly what String.split, LocalDate.plusMonths, or BigDecimal.setScale will return for an edge case, try it in JShell first and then write the code with confidence.

Practical Example: Exploring an API

Suppose you need to compute a subscription's renewal date and are unsure how month arithmetic handles the end of a month:

jshell> import java.time.*

jshell> LocalDate.of(2026, 1, 31).plusMonths(1)
$2 ==> 2026-02-28

jshell> LocalDate.of(2028, 1, 31).plusMonths(1)
$3 ==> 2028-02-29

jshell> LocalDate.of(2026, 1, 31).plusMonths(1).plusMonths(1)
$4 ==> 2026-03-28

jshell> LocalDate.of(2026, 1, 31).plusMonths(2)
$5 ==> 2026-03-31

Four lines reveal an important behavior: plusMonths clamps to the last valid day of the target month (February 28, or 29 in a leap year), and adding one month twice is not the same as adding two months at once, because the clamped day carries forward. A billing system that renews by repeatedly adding one month would drift from the 31st to the 28th permanently. Discovering this in JShell, before writing the billing code, costs seconds; discovering it from customer complaints costs far more.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about JShell Basics and get answers drawn from it.

Signed-in readers only.