JShell 的限制是什么?

What are the limits to JShell?

我发现了 question, and this ,它非常有趣,引出了几个问题,至少对我来说是这样:

相当开放式的问题,但是jshell 限制到哪里?显然,GUI 应用程序不在 jshell 解决方案或 IDE 替换的域中:

Out of scope are graphical interfaces and debugger support. The JShell API is intended to allow JShell functionality in IDEs and other tools, but the jshell tool is not intended to be an IDE.

维恩图或其他视觉效果的奖励积分。

当然,片段的大小应该受到限制。我想问的是什么类型的问题是snippets解决不了的。

另见:

https://openjdk.java.net/jeps/222

https://openjdk.java.net/jeps/330

回答更新后的问题

所有问题都可以用代码片段解决(也可以用足够复杂的 shell 脚本)。但是 JShell 最适合用于调试和学习 java - full-fledged 程序对于所有其他 use-cases.

来说要灵活得多

JShell、.jsh 和 java MyClass.java

JShell is an interactive shell for trying out java code. Essentially, it is a REPL Java。

由于 JShell 完全是关于您输入代码片段,然后对其进行评估,并且将这些片段放在一个文件中而不是多次编写它们通常很有意义,因此 JShell 支持 .jsh 脚本,这包含由 JShell 解释的片段集合。从这个意义上说,这类似于 bash 接受 .sh 文件或 command.com 接受 .bat 文件——逐行键入它们等同于导入它们。

Single-source java-file execution 是一个非常不同的野兽。从JDK 11开始,

java MyClass.java arg1 arg2 arg3

通过您的本地脚本相当于编写

TMPDIR=$(mktemp -d)
javac -d $TMPDIR MyClass.java
java -cp $TMPDIR MyClass arg1 arg2 arg3
rm -rf $TMPDIR

这使得 single-source 文件可以从命令行使用单个命令快速执行,而不会在整个地方留下编译的 classes(不需要创建实际的临时目录) ,因为 java 可以将那些 class 存储在内存中)。由于他们在 java 中已经有 3 种其他执行模式(对于 classes、jar-files 和模块),将其添加为第四种模式并不是一件容易的事。

由于 OP 想要一张照片:

Java作为脚本语言

现在区别已经很清楚了(.jsh 用于 JShell,single-source java 可执行文件仅用于,你猜对了,single-source java 可执行文件),使用 Java 作为脚本语言怎么样?

您一直可以选择编写启动器;例如,

 #!/bin/bash
 java -jar MyApp.jar

已经工作了很长时间。直接命名 class 在技术上是可行的,但不是很有用,因为 jar 文件在分发二进制文件时要方便得多——一方面,它们避免将包结构镜像为一堆文件夹。然而,将启动器脚本与实际 java 代码分开仍然有些不友好:您现在需要将两者放在一起,或者至少让启动器能够找到要启动的实际 .jar。

现在,他们还引入了以下快捷方式:无论文件名或扩展名如何,您都可以使用 "shebang prefix" 分发您的 java 源,如下所示:

#!/path/to/java --source 11
<source of MyClass.java>

将其标记为可执行文件,然后从 command-line 启动它,就像您可以启动任何其他可执行文件一样。例如,将其复制并粘贴到 helloworld 文件中(并在尝试 运行 之前修复 jdk 位置):

#!/opt/jdk-11.0.1/bin/java --source 11 
public class Test {
    public static void main(String ... args) {
        System.out.println("Hello " + (args.length == 0 ? "world!" : args[0]));
    }
}

将其标记为可执行文件后,您可以直接使用

启动它
$ ./helloworld
Hello world!

甚至它的论点都是正确的:

$ ./helloworld Bob!
Hello bob!

对于小程序,如果您不需要走出 JDK 来引入额外的库,现在分发 java 代码 command-line 利用。

Java 仍然不是 "scripting language"(它永远不会与 python 竞争),而是

  • 它有一个非常好的 REPL 循环
  • 你可以更轻松地执行短程序

嗯,当然,就 IDE 和图形用户界面可以提供的范围而言,它仅限于带来一个普通的 REPL 实用程序。与单一源代码程序相比,我会更多地谈论它的功能。使其与单一源代码程序区别开来的特点:

  • 编辑历史
  • tab 补全
  • 自动添加所需的终端分号和
  • 可配置的预定义导入和定义

Single-File Source-Code Programs JEP 的替代项中所述:

We could delegate the task of "one-off runs" to the jshell tool. While this may at first seem obvious, this was an explicit non-goal in the design of jshell.

The jshell tool was designed to be an interactive shell, and many design decisions were made in favor of providing a better interactive experience.

Burdening it with the additional constraints of being the batch runner would detract from the interactive experience.


!!!限制和行为!!!

另一方面,在使用 JShell 进行实际操作而不是简单地阅读文档时,人们通常会发现的一些限制(假定的功能)是:

  • final变量的使用

  • 当然

  • jshell 与 IDEs 的集成

  • 禁用历史记录Disable JShell history

  • 重新声明的变量应该被重置

  • 使用 jshell 创建模块

  • 正在导入私有包类

  • 对象范围

  • 清除jshell控制台

!!!功能和更多!!!

有关链接的更多详细信息,使其比单文件源代码程序更具优势:

  • 为什么以及如何

  • 为项目导入类路径

  • 运行 通过 JShell 的应用程序 How to run a java application with jshell?

  • 设置自定义反馈模式

  • 启动时加载脚本

  • 列出活动方法

  • 运行一个jshell文件

  • 用jshell执行javascript

  • 如何在jshell中使用方法引用Is there a way to use method references for top-level functions in jshell?