In the previous guide in this series, you learned the basics of JShell.
In this guide, you'll learn how to manage code snippets and use JShell to explore libraries.
JShell has a few more commands on its own. You can see the complete list by typing /help
or /?
:
1jshell> /help
2| Type a Java language expression, statement, or declaration.
3| Or type one of the following commands:
4| /list [<name or id>|-all|-start]
5| list the source you have typed
6| ...
The most useful commands are probably the ones that help you manage code snippets.
The first one is list
, which lists by default, all the valid statements you have typed since starting the session:
1jshell> /list
2
3 1 : "Hello World"
4 2 : $1
5 3 : System.out.println($1)
There's another command that does something similar: /history
. The difference is that /history
presents all the statements (valid or not) and commands that you have typed:
1jshell> /history
2/help
3"Hello World"
4$1
5System.out.println($1)
6Sys
7/list
8/history
You can also list only variables with /var
, only methods with /methods
, or only types with /types
:
1jshell> /vars
2| String $1 = "Hello World"
However, the advantage of /list
is that it shows you a numeric identifier for each snippet that you can use to rerun it with /<id>
:
1jshell> /3
2System.out.println($1)
3Hello World
Delete it with the /drop
command:
1jshell> /drop 2
2
3jshell> /list
4
5 1 : "Hello World"
6 3 : System.out.println($1)
Or edit it:
1jshell> /edit 1
In this case, a window will open with a simple editor that will help you modify the snippet:
This editor comes in handy to add or modify multi-line statements like classes or methods and it won't be closed until you click on the Exit (saving the changes) or Cancel (discarding the changes) buttons.
However, in the case of implicit variables, notice that instead of modifying the variable, JShell creates another variable with the new value:
1jshell> /edit 1
2$4 ==> "Hello World modified"
3
4jshell> /list
5
6 1 : "Hello World"
7 3 : System.out.println($1)
8 4 : "Hello World modified";
9
10jshell>
This doesn't happen with explicitly named variables or types.
You can also use the name of the variable or type with these commands. For example, using the Book
class defined in the previous section:
1jshell> class Book {
2 ...> private String title;
3 ...> public void setTitle(String title) { this.title = title; }
4 ...> public String getTitle() { return title; }
5 ...> }
6| created class Book
7
8jshell> /list
9
10 1 : "Hello World"
11 3 : System.out.println($1)
12 4 : "Hello World modified";
13 5 : class Book {
14 private String title;
15 public void setTitle(String title) { this.title = title; }
16 public String getTitle() { return title; }
17 }
18
19jshell>
We can edit it with the command:
1jshell> /edit Book
If we modify the class in this way:
1class Book {
2private String title = "<NO TITLE>";
3public void setTitle(String title) { this.title = title; }
4public String getTitle() { return title; }
5public String toString() { return "Book: " + title; }
6}
And click on Exit, JShell will update the definition of the class (notice that the ID also changed):
1jshell> /edit Book
2| replaced class Book
3
4jshell> /list
5
6 1 : "Hello World"
7 3 : System.out.println($1)
8 4 : "Hello World modified";
9 6 : class Book {
10 private String title = "<NO TITLE>";
11 public void setTitle(String title) { this.title = title; }
12 public String getTitle() { return title; }
13 public String toString() { return "Book: " + title; }
14 }
If you execute the /edit
command without an argument, the editor will let you modify all the current statements in the session (and even add some if you want):
As mentioned before, JShell does an excellent job helping us explore new libraries. So, let's assume we want to try out the Guava library.
You can download the JAR file of Guava 23.0 (the latest at this time) here.
In a JShell session, you get the following set of imports by default:
1jshell> /imports
2jshell> /imports
3| import java.io.*
4| import java.math.*
5| import java.net.*
6| import java.nio.file.*
7| import java.util.*
8| import java.util.concurrent.*
9| import java.util.function.*
10| import java.util.prefs.*
11| import java.util.regex.*
12| import java.util.stream.*
You can import other packages, but how does JShell know where to look for custom packages?
Consider the following case:
1jshell> import com.mycompany.*
What you have to do is add the packages to the JShell classpath with the /env -class-path <path>
command (if we already started a JShell session) or the option $jshell --class-path <path>
(on the command-line).
You can specify a directory (in this example, it's the current directory):
1jshell> /env -class-path .
Or a list of directories, JARs, or ZIP archives to search for compiled class files (the list must be separated with :
on Linux/Mac and ;
on Windows). You can find out more by executing /help context
.
This way, assuming you have downloaded the Guava JAR in C:\
, we can execute the following command:
1jshell> /env -class-path C:\guava-23.0.jar
2| Setting new options and restoring state.
As you can see from the message, it will restore the session with the new classpath setting, which means that it will run all valid snippets executed until that point.
If the library you want to test depends on other libraries, you have to download those dependencies and add them to the classpath too.
Now, you can import the classes from Guava's packages. Start typing:
1jshell> import com.google.common.primitives.
And then press Tab so JShell can present some options:
1jshell> import com.google.common.primitives.
2Booleans Bytes Chars Doubles Floats
3ImmutableDoubleArray ImmutableIntArray ImmutableLongArray Ints Longs
4Primitives Shorts SignedBytes UnsignedBytes UnsignedInteger
5UnsignedInts UnsignedLong UnsignedLongs
This is where JShell auto-completion comes in handy.
JShell's auto-completion capabilities allow you to view:
Let's import the Longs
class:
1jshell> import com.google.common.base.Longs
If we type Longs.
and press Tab, JShell will show the class’s static members:
1jshell> Longs.
2BYTES MAX_POWER_OF_TWO asList(
3class compare( concat(
4constrainToRange( contains( ensureCapacity(
5fromByteArray( fromBytes( hashCode(
6indexOf( join( lastIndexOf(
7lexicographicalComparator() max( min(
8stringConverter() toArray( toByteArray(
9tryParse(
The names that are not followed by parentheses (like BYTES
) are static variables. All the other names are static methods:
()
(like lexicographicalComparator()
), it means that the method doesn't require any arguments.(
, it means that the method requires at least one argument or that it is overloaded.If you want to know more about the method indexOf
type the name of this method and its opening parenthesis (the name can be auto-completed too), and press Tab:
1jshell> Longs.indexOf(
2Signatures:
3int Longs.indexOf(long[] array, long target)
4int Longs.indexOf(long[] array, long[] target)
5
6<press tab again to see documentation>
If you press Tab again, you'll see the Javadoc of the first overload:
1jshell> Longs.indexOf(
2int Longs.indexOf(long[] array, long target)
3<no documentation found>
4
5<press tab to see next documentation>
In this case , there is no documentation is found. But you can keep pressing Tab to see the documentation of the next methods:
1jshell> Longs.indexOf(
2int Longs.indexOf(long[] array, long[] target)
3<no documentation found>
4
5<press tab again to see all possible completions; total possible completions: 600>
You can do this kind of exploration with any class, even at class level:
1jshell> String
2String StringBuffer StringBufferInputStream
3StringBuilder StringIndexOutOfBoundsException StringJoiner
4StringReader StringTokenizer StringWriter
5Strings
6
7Signatures:
8java.lang.String
9
10<press tab again to see documentation>
11
12jshell> String
13java.lang.String
14The String class represents character strings. All string literals in Java programs, such as
15"abc", are implemented as instances of this class.
16...
17Unless otherwise noted, passing a null argument to a constructor or method in this class will
18
19<press tab again to see next page>
Or with any object to show its instance members:
1jshell> "Hello".
2charAt( chars() codePointAt( codePointBefore( codePointCount(
3...
JShell is an important addition to the Java language. Users can easily and quickly verify things like return types, adjust formatting options, or try out libraries or language features.
Hopefully this guide taught you what you needed to know about how to work with various types of code snippets in JShell, some of its useful commands, and its auto-completion capabilities to explore a class’ members and documentation.
Of course, this guide only scratches the surface. Advanced users should look forward to learning more about feedback modes, custom options (like setting a custom editor), and ways of integrating JShell into your Java programs. A good resource to learn about some of these topics is Robert Field's tutorial on JShell.