JShell教程

什么是JShell

JShell工具是一个命令行工具,通过提供Java编程语言元素的交互使用来促进探索性编程。JShell是一个REPL(读取-评估-打印循环)。无论是学习Java语言还是探索陌生的代码(包括新的Java API),它都是理想的选择。典型的Java开发意味着编写一个完整的程序,然后对其进行编译(修复所有错误),运行它,找出问题所在,进行编辑和重复。使用JShell,您可以一次输入一个程序元素,立即查看结果并进行相应调整。在开发过程中,可以将代码粘贴到JShell中,和/或将工作代码从JShell粘贴到程序编辑器中。

启动JShell

首先安装JDK9。JDK 9中包含JShell。要启动JShell工具,只需jshell在命令行中键入:

% jshell

在本教程中,bold fixed-width font将始终使用它来指示您键入的文本。

如果确实输入了JShell工具,请键入/exit以退出:

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

jshell> /exit
|  Goodbye

对于本教程,所有示例都使用详细模式。为了使您看到的内容匹配,我建议您以详细模式进行操作。一旦熟悉了,您可能会希望以正常或更简洁的模式运行。要以详细模式启动JShell,请输入:

% jshell -v

片段

尝试一下

JShell接受Java语句,变量,方法和类定义,导入和表达式。我将把这些Java代码片段称为片段。例如,您可以在提示符下输入一条语句,发生任何副作用并显示任何输出:

jshell> System.out.println("Hi");
Hi
                                                                                   
jshell>

默认情况下,JShell将为您提供有关您输入内容的信息。在这里,定义了一个变量:

jshell> int x = 45
x ==> 45
|  created variable x : int

首先,显示结果,可以读取:变量x的值为45。由于我们处于详细模式,因此还对发生的情况进行了说明,信息性消息以竖线开头。注意:将显示创建的变量的名称和类型。

请注意,如果缺少终止分号,则会自动将其添加到代码段的末尾。

当输入没有命名变量的表达式时,将创建一个临时变量,以便稍后可以引用该值:

jshell> 2 + 2
$3 ==> 4
|  created scratch variable $3 : int

jshell> String twice(String s) {
   ...>    return s + s;
   ...> }
|  created method twice(String)

jshell> twice("Ocean")
$5 ==> "OceanOcean"
|  created scratch variable $5 : String

改变定义

要更改您先前输入的变量,方法或类的定义,只需输入一个新定义。例如,我们上面定义的方法可以获得新的新定义:

jshell> String twice(String s) {
   ...>     return "Twice:" + s;
   ...> }
|  modified method twice(String)

jshell> twice("thing")
$7 ==> "Twice:thing"
|  created scratch variable $7 : String

请注意,它不是created method像以前那样说“ modified method” ,而是说“ ”-这意味着定义已更改,但是具有相同的签名,因此所有现有用法继续有效。

您也可能以不兼容的方式更改定义。例如:

jshell> String x
x ==> null
|  replaced variable x : String
|    update overwrote variable x : int

我们已经更改了变量x的类型,请注意,它现在显示为“ replaced”。稍后对此进行更多讨论。

我们以详细的反馈模式启动了JShell,因此它非常健谈。您可以使用/set feedback命令设置输出的数量和格式,例如/set feedback concise。如果您打算通过从其他窗口进行粘贴来主要使用JShell,则可能希望使用一种反馈模式,该模式没有提示并且只有错误反馈:/set feedback silent

前向参考

由于JShell的目标是支持探索性编程(并且某些形式的编程要求这样做),因此JShell允许您定义其主体引用尚未定义的方法,变量或类的方法。假设您想定义一个球体的体积的方法,可以输入公式:

jshell> double volume(double radius) {
   ...>     return 4.0 / 3.0 * PI * cube(radius);
   ...> }
|  created method volume(double), however, it cannot be invoked until variable PI, and method cube(double) are declared

JShell允许定义,但警告尚未定义的内容。可以引用该定义,但是如果尝试执行,它将失败:

jshell> double PI = 3.1415926535
PI ==> 3.1415926535
|  created variable PI : double

jshell> volume(2)
|  attempted to call method volume(double) which cannot be invoked until method cube(double) is declared

jshell> double cube(double x) { return x * x * x; }
|  created method cube(double)
|    update modified method volume(double)

jshell> volume(2)
$5 ==> 33.510321637333334
|  created scratch variable $5 : double

有了所有定义后,批量即可使用。

我将使用此代码来说明有关不兼容替换的更多信息。假设您对PI的精度不满意:

jshell> BigDecimal PI = new BigDecimal("3.141592653589793238462643383")
PI ==> 3.141592653589793238462643383
|  replaced variable PI : BigDecimal
|    update modified method volume(double) which cannot be invoked until this error is corrected: 
|      bad operand types for binary operator '*'
|        first type:  double
|        second type: java.math.BigDecimal
|          return 4.0 / 3.0 * PI * cube(radius);
|                 ^------------^
|    update overwrote variable PI : double

PI的新定义与volume()的定义类型不兼容。由于我们处于详细模式,因此会显示受更改影响的其他定义的更新信息-在此描述不兼容。请注意,详细模式是唯一会显示更新信息的内置反馈模式。在其他反馈方式下,直到执行代码,才会显示警告-这是为了防止出现不必要的更新。在所有情况下,执行volume()方法都会显示问题:

jshell> volume(2)
|  attempted to call method volume(double) which cannot be invoked until this error is corrected: 
|      bad operand types for binary operator '*'
|        first type:  double
|        second type: java.math.BigDecimal
|          return 4.0 / 3.0 * PI * cube(radius);
|                 ^------------^

例外情况

在异常回溯中,REPL输入的代码中的位置显示为#id /行号,其中代码段ID是/ list中显示的数字,而行号是代码段中的行号。因此,下面的代码段#1中又发生了例外,又名divide()在diving的第二行:

jshell> int divide(int x, int y) {
   ...>     return x / y;
   ...> }
|  created method divide(int,int)

jshell> divide(5, 0)
|  java.lang.ArithmeticException thrown: / by zero
|        at divide (#1:2)
|        at (#2:1)
                             
jshell> /list
                                                            
   1 : int divide(int x, int y) {
           return x / y;
       }                                                                                                                                                                
   2 : divide(5, 0)

制表符完成-代码段

按Tab键完成当前输入。例如:

jshell> vol<标签>

将被替换为:

jshell> volume(

如果存在多个完成,则会列出一组完成:

jshell> System.c<标签>
class                 clearProperty(        console()             currentTimeMillis()   

jshell> System.c

将添加任何常用字符,并将光标放置在输入的末尾,以便可以添加更多字符。

当您在方法调用的开括号中时,选项卡将显示上面的补全(如果有任何有趣的显示),并将显示参数类型:

jshell> "hello".startsWith(<标签>
Signatures:
boolean String.startsWith(String prefix, int toffset)
boolean String.startsWith(String prefix)

<press tab again to see documentation>

jshell> "hello".startsWith(

再次按tab将显示第一种方法的文档的纯文本版本。

jshell> "hello".startsWith(<标签>
boolean String.startsWith(String prefix, int toffset)
Tests if the substring of this string beginning at the specified index starts with the
specified prefix.

Parameters:
prefix - the prefix.
toffset - where to begin looking in this string.

Returns:
true if the character sequence represented by the argument is a prefix of the substring of this
          object starting at index toffset ; false otherwise. The result is false if toffset is
          negative or greater than the length of this String object; otherwise the result is
          the same as the result of the expression
                    this.substring(toffset).startsWith(prefix)
                    

<press tab to see next documentation>

jshell> "hello".startsWith(

摘要转换

输入需要导入的标识符时,按<shift-tab> i(即在按住tab的同时按住shift,然后释放并按i),将出现一个菜单,可让您自动添加导入:

jshell> new JFrame<shift-tab>i
0: Do nothing
1: import: javax.swing.JFrame
Choice: 1
Imported: javax.swing.JFrame

jshell> new JFrame

注意:可能有不止一种导入选择。

输入表达式后,可以使用<shift-tab> v将表达式转换为变量声明。也就是说,表达式将成为变量声明的初始化程序,而变量的类型将成为表达式的类型:

jshell> new JFrame("Demo")<shift-tab>v
jshell> JFrame | = new JFrame("Demo")

光标将定位在变量名应到达的位置。输入变量名称,然后按回车键

注意:表达式必须有效,否则转换请求将被忽略。因此,在变量转换之前需要导入JFrame

有时,表达式的结果类型尚未导入。在这种情况下,<shift-tab> v将提供导入和创建变量的功能。我们从上方继续,输入变量名'frame'并按回车键:

jshell> JFrame frame = new JFrame("Demo")
frame ==> javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden, ... tPaneCheckingEnabled=true]
|  created variable frame : JFrame

jshell> frame.setSize(300, 200)

jshell> frame.setVisible(true)

jshell> frame.getGraphics()<shift-tab>v
0: Do nothing
1: Create variable
2: import: java.awt.Graphics. Create variable
Choice: 2
Imported: java.awt.Graphics

jshell> Graphics | = frame.getGraphics()

应输入图形上下文变量的名称。

指令

命令-简介

JShell具有许多用于控制环境和显示信息的命令。它们与代码片段的区别在于前导斜线。您可以使用/ vars,/ methods和/ types命令获取有关当前变量,方法和类型的信息。您可以使用/ list命令获取输入的摘要列表。例如:

jshell> /vars
|    int x = 45
|    int $3 = 4
|    String $5 = "OceanOcean"

jshell> /methods
|    twice (String)String

jshell> /list

   1 : System.out.println("Hi");
   2 : int x = 45;
   3 : 2 + 2
   4 : String twice(String s) {
         return s + s;
       }
   5 : twice("Ocean")

您会注意到,将显示变量的类型和值以及方法的类型签名。

JShell具有启动项,这些启动项在JShell启动之前会以静默方式自动执行,因此您可以快速开始工作。这些未列出,除非你要求看他们/list -start/list -all

jshell> /list -all

  s1 : import java.util.*;
  s2 : import java.io.*;
  s3 : import java.math.*;
  s4 : import java.net.*;
  s5 : import java.util.concurrent.*;
  s6 : import java.util.prefs.*;
  s7 : import java.util.regex.*;
   1 : System.out.println("Hi");
   2 : int x = 45;
   3 : 2 + 2
   4 : String twice(String s) {
         return s + s;
       }
   5 : twice("Ocean")

默认的启动项是几种常见的导入。您可以使用以下/set start命令个性化启动条目:有关此信息,请键入:/ help / set start。/save -start如果您希望创建文件作为默认启动的变体,则此命令很有用。

使用/ help获得命令列表。

其他重要命令包括/exit离开JShell,/save保存您的代码片段以及/open将它们读回。

制表符补全-命令

制表符补全也适用于命令和命令参数:

jshell> /<标签>
/!          /?          /drop       /edit       /env        /exit       /help
/history    /imports    /list       /methods    /open       /reload     /reset      
/save       /set        /types      /vars       

<press tab again to see synopsis>

jshell> /

独特的完成是就地完成的:

jshell> /l<标签>

替换为:

jshell> /list

选项卡补全适用于命令选项:

jshell> /list -<标签>
-all       -history   -start     

<press tab again to see synopsis>

jshell> /list -

请注意消息,另一个选项卡将显示命令摘要,该摘要是命令的简短描述。再次标签将显示/ help文档:

jshell> /list -<tab> <tab> <tab>
list the source you have typed

<press tab again to see full documentation>

jshell> /list -
Show the source of snippets, prefaced with the snippet id.

/list
    List the currently active snippets of code that you typed or read with /open

/list -start
    List the automatically evaluated start-up snippets

/list -all
    List all snippets including failed, overwritten, dropped, and start-up

/list <name>
    List snippets with the specified name (preference for active snippets)

/list <id>
    List the snippet with the specified snippet id

jshell> /list -

唯一的参数完成是就地完成的:

jshell> /list -a<标签>

替换为:

jshell> /list -all

代码段名称也可以用制表符补全:

jshell> /ed v<标签>

替换为:

jshell> /ed volume

在命令的文件参数位置中的using选项卡显示可用文件:

jshell> /open <标签>
myfile1      myfile2    definitions.jsh

<press tab again to see synopsis>

jshell> /open 

唯一文件名完成是就地完成的:

jshell> /open d<标签>

is replaced with:

jshell> /open definitions.jsh

命令缩写

命令,/set子命令,命令参数和命令选项都可以缩写,只要它们是唯一的即可。

因为,/list是唯一以开头的命令,唯一以开头/l/list命令选项-a-all

jshell> /list -all

可以缩写为:

jshell> /l -a

并且,/set是唯一以开头的命令,唯一以开头/se/set子命令fefeedback,并且,除非添加了用户模式,否则verbose是唯一以开头的反馈模式v。命令:

jshell> /set feedback verbose 

可以缩写为:

jshell> /se fe v

请注意,/s由于/save开头相同,这还不够。如有疑问,可以使用制表符补全。

编者

为了更轻松地编辑过去的条目,尤其是很多行中的条目,您可以通过提供片段的名称或ID(/ list中的数字)来调用片段中的编辑器:

jshell> /edit volume

或者,对于所有代码段并输入新的代码段,/edit而无需添加参数。当您保存在编辑器中时,将输入任何已更改或新的代码段,您将在JShell窗口中看到这些代码段的反馈,但是不会有JShell提示,并且您无法在JShell窗口中输入命令或代码段,直到编辑器被关闭。

如果您未指定编辑器,则将提供一个简单的内置编辑器。指定要使用/set editor命令调用的编辑器。该命令的参数是您要使用的外部编辑器。该编辑器必须打开自己的窗口。例如:

jshell> /set editor kwrite
|  Editor set to: kwrite

jshell> /edit ...

用户在外部编辑器窗口中定义x并选择保存

|  created variable x of type int with initial value 6

用户关闭外部编辑器

jshell> 

外壳编辑

用户输入编辑基于JLine2构建,其功能类似于Emacs模式下的BSD编辑线和GNU阅读线。它可以用于编辑当前行或访问整个历史记录,这些历史记录可以通过多次使用jshell工具来追溯。

本教程将使用“ Ctrl-x”表示按住Control键,然后按x键。“ Meta-x”表示按住Meta键(通常是左Alt键),然后按x键。

一行中的基本导航使用向右/向左箭头键,或者使用Ctrl-b和Ctrl-f(用于后退和前进)。历史记录中各行之间的导航使用向上/向下箭头键。因此,按一下向上箭头一次会将当前行替换为先前的命令或代码段行。再次按向上箭头可将您带到之前的那一行。历史记录包含命令和代码段行-请注意,代码段可能有多行,上/下箭头将在代码段的各个行之间导航。

运动命令
行动
返回 输入当前行
左箭头 向后移动一个字符
右箭头 向前移动一个字符
向上箭头 向上移动一行(在历史记录中向后移动)
下箭头 向下移动一行(向前浏览历史记录)
Ctrl-a 移至行首
Ctrl-e 移至行尾
元b 向后移动一个字
元f 前进一个字

历史导航

JShell维护代码段和命令的历史记录。您可以浏览此历史记录,以使用向上/向下/向左/向右箭头重新输入或编辑先前的输入。输入的文本将被插入。Delete键可用于删除文本。按Enter键再次接受历史记录行(是否已修改)。

您可以使用向上控制和向下控制(即在按住向上或向下键的同时按住Control键)来一次移动代码段。

例如:

jshell> class C {                                                                                                                                                       
   ...>   int x;                                                                                                                                                        
   ...> }                                                                                                                                                               
|  created class C                                                                                                                                                      
                                                                                                                                                                        
jshell> /list                                                                                                                                                           
                                                                                                                                                                        
   1 : class C {                                                                                                                                                        
         int x;                                                                                                                                                         
       }                                                                                                                                                                
                                                                                                                                                                    
jshell> <向上箭头>

向上箭头键将使该行显示:

jshell> /list                                                                                                                                                           

再按一次向上箭头将显示:

jshell> }

类定义的最后一行。按下向下箭头将返回/list命令,然后按下return将执行该命令:

jshell> /list                                                                                                                                                           
                                                                                                                                                                        
   1 : class C {                                                                                                                                                        
         int x;                                                                                                                                                         
       }                                                                                                                                                                

Ctrl-向上箭头将按摘要显示。因此,对于单行代码段,Ctrl-向上箭头的行为类似于向上箭头。但是,对于多行代码段(如C类),它将占据代码段的顶部。

修改中

只需键入即可将文本添加到当前光标位置。Delete键将删除光标右侧的字符,Backspace键将删除左侧的字符。

删除命令
行动
删除 删除光标下的字符
退格键 删除光标前的字符
Ctrl-k 杀死(删除)从光标到行尾的文本
从光标杀到单词结尾
Ctrl-w 从光标杀死前一个空格
Ctrl-y 将最近杀死的文本拖入(粘贴)到行中
Ctrl-y之后,按可以循环显示先前被杀死的文本

搜索和更多

搜索历史是一个强大的工具。按Ctrl-r,然后按要在历史记录中搜索的字符串。搜索将向后进行,从您最近的主菜开始,并包括jshell工具的先前会话。假设前面的示例,在提示符下按Ctrl-r:

jshell> <Ctrl-r>

将提示替换为:

(reverse-i-search)`': 

键入“班级”会将显示更改为:

(reverse-i-search)`class': class C {

显示带有文本“ class”的最新行。搜索是增量的,因此仅使用第一个字符“ c”来检索此行。您可以通过反复按Ctrl-r继续在历史记录中进行更早的搜索。Ctrl-s会将搜索移回当前位置。

您可以使用Ctrl-x定义键盘宏,后跟一个带括号的“ Ctrl-x(”,然后输入您的文本,最后键入“ Ctrl-x”)。当您希望使用宏时,输入“ Ctrl-x e”。

杂项命令
行动
Ctrl-r 向后搜索历史
Ctrl-s 搜寻历史
Ctrl-x( 开始输入宏
Ctrl-x) 完成宏
Ctrl-x e 使用宏

有关更多信息,请参见JLine2用户信息GNU Readline文档

使用外部代码

设置类路径

可以连接jshell工具访问的外部代码的一种方法是设置类路径。可以在命令行上设置类路径:

 % jshell --class-path myOwnClassPath

您的类路径应指向您要访问的软件包的目录或JAR文件。该代码必须编译到类文件中。无法从JShell访问默认包(也称为未命名包)中的代码。一旦设置了类路径,就可以导入这些包:

jshell> import my.cool.code.*

您还可以使用“ / env”命令设置类路径:

jshell> /env --class-path myOwnClassPath
|  Setting new options and restoring state.

请注意,此命令将重置执行状态,并使用新的类路径设置(或其他环境设置)重新加载当前的所有代码段。

设置模块选项

类似地,可以在jshell工具命令行或/ env的选项中设置模块路径,指定要解析的其他模块以及指定的模块导出:

 % jshell --module-path myOwnModulePath  --add-modules my.module

要查看当前环境设置,请使用不带参数的'/ env'

 jshell> /env
 |     --add-modules my.module
 |     --module-path myOwnModulePath
 |     --class-path myOwnClassPath

有关详细信息,请参见:

jshell> /help context

反馈模式

设置反馈模式

反馈模式是命名的用户交互配置。有内置模式,用户可以创建自定义模式。内置模式无法修改,但可以将副本作为用户定义模式的基础。有四种内置模式,按照详细程度的降序排列:详细,正常,简洁和静音。下表概述了不同之处:

模式 价值片段 宣言 更新 指令 提示
冗长的 名称==>值(和描述) \ njshell>
正常 名称==>值 没有 \ njshell>
简洁 名称==>值(仅表达式) 没有 没有 没有 jshell>
无声 没有 没有 没有 没有 ->

其中的“值片段”表示对具有值的片段(如表达式,赋值和变量声明)显示的内容;“声明”表示是否对方法,类,枚举,接口和注释接口的声明有反馈;“更新”指示是否显示除当前代码段以外的更改;“命令”指示命令是否给出指示成功的反馈。

除非通过命令行标志或/set feedback命令设置,否则反馈模式将为“正常”。该/set feedback命令设置反馈模式:

jshell> /set feedback verbose 
|  Feedback mode: verbose

jshell> 2 + 2
$1 ==> 4
|  created scratch variable $1 : int

jshell> /set feedback silent 
-> 2 + 2
-> /set feedback normal 
|  Feedback mode: normal

jshell> 2 + 2
$3 ==> 4

jshell> /set feedback concise 
jshell> 2 + 2
$4 ==> 4
jshell> 

请注意,当设置为“正常”或“详细”时,命令反馈会告知您已发生这种情况,而“简洁”和“沉默”则没有。还要注意对表达式的三种不同形式的反馈(包括无声反馈)。

要查看当前和可用的反馈模式,请使用/set feedback不带参数的命令。请注意,当前模式显示为将其设置的命令:

jshell> /set feedback 
|  /set feedback verbose
|  
|  Available feedback modes:
|     concise
|     normal
|     silent
|     verbose

定义反馈模式

模式有三种设置:提示,截断和格式。假设您希望更改提示。内置模式无法更改,但是您可以轻松创建现有模式的副本-第一步是:

jshell> /set mode mine normal -command
|  Created new feedback mode: mine

新模式“ mine”是“ normal”模式的副本,该-command选项表示您要命令反馈(上表的“ Commands”列)。如果在您的模式下,您不希望命令描述发生的操作(例如,上面的“ ||创建新的反馈模式:我的”),请使用-quiet代替-command

像所有/set命令一样,使用/set prompt不带参数的命令将给出当前设置:

jshell> /set prompt normal
|  /set prompt normal "\njshell> " "   ...> "

第一个字符串是常规提示,第二个字符串是继续提示,如果代码段扩展到多行,则使用该提示。在这里,我们设置提示,切换到新模式以进行查看并进行测试:

jshell> /set prompt mine "\nmy mode: "  ".......: "

jshell> /set feedback mine
|  Feedback mode: mine

my mode: class C {
.......:   int x;
.......: }
|  created class C

my mode:

提示字符串中可能包含'%s',该字符串将被下一个代码段ID取代-请注意,用户在提示符下输入的内容可能未分配该ID,例如,它可能是错误或命令。

所有设置都有当前工具会话的持续时间(注意:它们不会通过重置/reset)。如果您希望它们在以后的会议中成为默认设置,请使用该-retain选项保留它们:

my mode: /set mode mine -retain

my mode: /set feedback mine -retain
|  Feedback mode: mine

my mode: /exit 
|  Goodbye
% jshell   
|  Welcome to JShell -- Version 9
|  For an introduction type: /help intro

my mode: 

显示值时,如果值太长,则会被截断。“太长”是由/set truncation命令确定的。如果没有设置,它将显示当前设置,这些设置是从普通模式继承的:

my mode: /set truncation mine 
|  /set truncation mine 80 
|  /set truncation mine 1000 expression,varvalue

my mode: String big = IntStream.range(0,1200).mapToObj(n -> "" + (char) ('a' + n % 26)).collect(Collectors.joining())
big ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv ... fghijklmnopqrstuvwxyzabcd"

在截短长度之后可选出现的选择器类型选择将执行该截短设置的条件。在这里,是大小写选择器,它指示要显示其值的代码段的种类。有关/help /set truncation选择器的详细信息,请参见。上面显示的设置表示值将被截断为80个字符,除非该值是表达式的值(expression大小写选择器)或变量的值,而仅通过输入变量名(varvalue大小写选择器)明确要求即可。顺序很重要,最后一个赢。如果顺序相反,则所有截断将为80个字符。

假设在我们的模式下,我们希望默认截断为100,并且仅在明确要求时使用长值。

my mode: /set truncation mine 100

my mode: /set truncation mine 300 varvalue

my mode: big + big
$2 ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi ... yzabcdefghijklmnopqrstuvwxyzabcd"

my mode: big
big ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu
vwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl ... jklmnopq
rstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"

my mode: /set mode mine -retain

注意:如果需要这些更改,则必须保留对模式的更改。

现在,将代码段输出更改为我们的首选项。

my mode: import java.beans.*

my mode: Locale.CANADA.getUnicodeLocaleAttributes()
$5 ==> []

从正常模式继承的格式中,导入不提供任何反馈,并且不显示值的类型。片段输出的格式是通过/set format命令设置的。对于某些模式,请尝试以下操作(无设置)以查看当前格式设置:

my mode: /set format mine

使用对此命令有广泛的帮助/help /set format。请立即阅读并参考。显示的主要反馈由该display字段确定。可以定义其他字段以帮助定义该display字段。(非静默的)预定义模式定义了几种,如上面命令的输出所示。这些是在我们的示例模式下继承的。以下是导入的显示定义:

my mode: /set format mine display "{pre}added import {name}{post}" import-added

my mode: /set format mine display "{pre}re-added import {name}{post}" import-modified,replaced

name字段预定义为代码段的名称。

my mode: import java.beans.*
|  re-added import java.beans.*

prepost领域有反馈输出的每一行的前缀和后缀字符。假设我们不喜欢竖线前缀:

my mode: /set format mine pre ""

my mode: void m() {}
created method m()

my mode: import java.beans.*
re-added import java.beans.*

my mode: /set feedback mine 
Feedback mode: mine

注意:这会影响所有反馈,包括命令反馈。

要在显示值时显示类型,最容易的是更改result由预定义模式定义的字段:

my mode: /set format mine result "{type} {name} = {value}{post}" added,modified,replaced-primary-ok

my mode: Locale.CANADA.getUnicodeLocaleAttributes()
Set<String> $11 = []

my mode: 2 + 2
int $12 = 4

我们希望result仅当它是新的/更新的(added,modified,replaced),位于输入的代码段(primary)且没有错误(ok)时才为非空。

要永久删除保留模式:

my mode: /set feedback verbose -retain
|  Feedback mode: verbose

jshell> /set mode mine -delete -retain

剧本

JShell脚本

JShell脚本是文件中的片段和JShell命令序列,每行一个。

脚本可以在编辑器中外部创建,也可以使用以下命令之一生成:

jshell> /save mysnippets.jsh

jshell> /save -history myhistory.jsh

jshell> /save -start mystartup.jsh

这些分别将当前活动的代码片段,所有代码片段和命令的历史记录(有效和无效)或当前启动脚本设置的内容保存到指定的脚本文件中。

脚本名称可以是操作系统文件名(如上)或以下预定义脚本之一:

脚本 内容
默认 默认启动(如果未设置)包括常用的导入声明
列印 定义JShell方法重定向到的printprintln以及printf在方法PrintStream
JAVASE 导入所有Java SE软件包,这很大,并且会导致明显的启动延迟

加载脚本

可以通过在jshell工具命令行上列出脚本来加载脚本:

% jshell mysnippets.jsh

或在/open命令上:

jshell> /open PRINTING

启动脚本

每次重置jshell工具时,都会加载启动脚本。关于初始启动和与复位命令时复位(/reset/reload,和/env)。除非用户设置,否则将使用默认的启动脚本(DEFAULT),这将定义常用的导入声明。注意:Java语言定义自动导入java.lang包,因此不需要显式导入。

要设置启动脚本,请使用/set start

jshell> /set start mystartup.jsh

jshell> /reset
|  Resetting state.

与所有/set命令一样,除非使用该-retain标志,否则设置的持续时间为当前会话。-retain如上所述,不带标志的使用通常仅用作安全测试启动脚本设置的机制。找到所需的设置后,可以使用以下方法保存:

jshell> /set start -retain

那么设置的启动脚本将在您下次调用jshell工具时加载。

请记住,仅在重置状态时,启动脚本才会加载到当前会话中。注意:存储的是文件的内容,而不是对文件的引用。仅在/set start运行命令时读取文件。相反,当使用预定义的脚本名称时,它们是通过引用提供的,并且可以使用JDK的新发行版进行更新。

也可以使用--startup命令行标志来指定启动脚本(注意,如果是唯一的,则可以缩写命令行标志):

% jshell --start mystartup.jsh

JShell的早期开发版本定义了printfJShell方法,该方法已从默认启动中删除,以确保与Java程序的剪切和粘贴兼容性。但是,使用不需要System.out.前缀的打印方法进行实验非常方便。您可以在上指定多个启动脚本/set start

jshell> /set start -retain DEFAULT PRINTING

jshell> /exit
|  Goodbye

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

jshell> println("Hello World!")
Hello World!

这会将启动程序设置为加载默认导入和打印定义。该-retain标志用于将它们设置为jshell工具未来会话的启动脚本。尝试使用/set start不带参数的,以查看此定义的启动的详细信息。

要在命令行上设置多个启动脚本,请--startup为每个脚本使用标志:

% jshell --start DEFAULT --start PRINTING
上一篇:java-在JShell中声明的方法是lambda?


下一篇:如何用jshell执行java脚本?