代码块
JShell 接受 Java 声明,变量、方法、类的定义,引用,以及表达式。这些Java代码片段被称为代码块。
话题
- 尝试代码块
- 改变定义
- 向前引用
- 异常
- 自动补齐功能
- 代码块转换
尝试代码块
Java 的代码块被输入到JShell中会被立刻执行。关于结果的反馈,执行的动作,以及出现的任何错误都会展现出来。可以使用这一节中的例子尝试下JShell。
为了得到最大程度的反馈,请带 -v 参数项启动JShell。
% jshell -v
welcome to Jshell --Version 9
for an introduction type: /help intro
在提示时输入下面的例子,看一下输出的结果
jshell> int x = 45
x ==> 45
| created variable x : int
第一,结果显示出来了。可以解读为:变量 x 的值为45。因为你在详尽模式下,所以关于发生了什么的描述被展示出来。展示的信息从一个竖条开始。注意到变量名和类型均被展现了出来。
注意:
分号结束符如果没有添加,会在每一个完整的代码块上适当被自动加上。
当一个表达式被输入时没有定义变量名,一个临时拼凑的变量名[1]将会被使用,以方便这个变量的值之后被引用。下面的例子显示了一个表达式的临时拼凑的变量名和一个的结果。例子同时也展现了当一个代码块需要不止一行的输入才能完成时,将使用…>作为持续的提示符。
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
改变定义
当你在拿代码做实验的时候,你可能发现变量,方法,或者类的定义并没有完成你想让他完成的事情。通过输入一个新的定义覆盖之前的定义从而轻易的改变定义。
为了改变一个变量,方法或者类的定义,简单的输入一个新的定义即可完成。例如,在尝试代码块这小节中定义的twice方法在下面的例子中得到了一个新的定义:
jshell twice(String s){
...> return "Twice:" + s;
...> }
| medified method twice(String)
jshell> twice("thing")
$7 ==> "Twice:thing"
| created scratch variable $7:String
注意与之前显示创造了方法不同,这个反馈是改变的方法。这个消息意味着定义改变了,但是方法有着同样的签名,因此所有存在的用法继续有效。
你同样可以以不一致的方式[2]改变定义。下面的展示了 x 如何从 int 改变为 String的:
jshell> int x = 45
x ==> 45
| created variable x: int
jshell> String x
x ==> null
| replaced variable x :String
| update overwrote variable x : int
变量 x 的类型改变了,而反馈现在显示的是替代。
调整反馈的程度
JShell以详细模式启动,该模式提供了很多的评论信息。你可使用/ set feedback命令来设置输出的信息量和形式,例如:/set feedback concise。如果你主要通过从其他窗口复制信息到JShell中,那你可能更倾向于一个没有提示仅有错误反馈的反馈机制。如果是这种情况,你可以使用 / set feedback silent命令。
向前引用
JShell可以接受引用到还没有定义的方法,变量,或者类的方法定义。这个是设计用来支持探索性编程,同时编程的一些形式需要这个功能。
作为例子,如果你想要一个定义计算球体的体积的方法,那么你可以为方法 volume 输入下面的公式:
jshell>double volume(double radius){
...> return 4.0 / 3.0 * PI * cude(radius);
...>}
| created method volume(double), however, it cannot be involved until variable PI,and method cube(double) are declared
JShell 允许这样的定义但是对于还未定义的变量给出警告。这个定义可以被引用,但如果尝试执行,但会失败,直到所需要的元素被定义:
jsehll> double PI = 3.1415926535
PI ==> 3.141592635
| created variable PI : double
jshell> volume(2)
| attempted to call method volume(double) which cannot be invoked until method cube(double) is declared
jsehll>double cube(double x) {return x * x * x;}
| created method cube(double)
| update modified method volume(double)
jsehll>volume(2)
$5 ==> 33.510321637333334
| created scratch variable $5 : double
随着所有的定义都就位了,volume 方法现在可以被调用了。
下面的方法更多被用来展示不一致的替换。例如,为了改变 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);
| ^------------^
异常
在异常回溯的情况下,反馈能够识别到代码块以及当有异常发生时,代码块里面的位置。
输入到JShell中的代码做出的位置以 #ID:行数 展示。其中 ID 可以使用 /list 命令查看,而 行数 则是一段代码片段中的行号。在下面的的例子中,异常出现在第一个代码片段中,也就是divide方法中,在其第二行。
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)
[1]. scratch variable 网上没有找到什么好的资料可以参考。
[2]. incompatible ways 待更好翻译
声明:本人翻译以意译为主,直译为辅。尽量尊重原文作者表达的意思,如有需要,会结合自己浅显的理解进行意译。译文中肯定会有不当之处,还请指正,十分感谢。
2/16/2018 8:18:49 PM translated by Truman