【问题标题】:What are the limits to JShell?JShell 的限制是什么?
【发布时间】:2019-05-20 21:05:27
【问题描述】:

我找到了this 的问题,还有这个other,很有趣,它引出了几个问题,至少对我来说:

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

超出范围的是图形界面和调试器支持。 JShell API 旨在允许 IDE 和其他工具中的 JShell 功能, 但是 jshell 工具并不是一个 IDE。

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

当然,sn-ps 的大小应该是有限的。我更想问的是sn-ps不能解决什么样的问题。

另见:

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

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

【问题讨论】:

  • 是的,这包括一个开放式问题,而且似乎过于宽泛而无法在 SO 上回答。也许参考相应的 JEP 以 openjdk.java.net/jeps/222openjdk.java.net/jeps/330 开始
  • JShell 的存在是因为有人说Java 必须有 REPL 工具。我从来不需要一个。
  • 老兄,我回答的时候你改了答案。哦,好吧,我在这个过程中学到了一点。是时候开始写博客了。
  • 所有问题都可以用 sn-ps 解决(也可以用足够复杂的 shell 脚本)。但是 JShell 最适合用于调试和学习 java - 一个成熟的程序对于所有其他用例来说更加灵活。
  • 谢谢,@nullpointer。我会回到JShell,但这有点有趣。我当然可以将其用作教学工具。

标签: java scripting jvm system-administration jshell


【解决方案1】:

回答更新后的问题

所有问题都可以使用 sn-ps 解决(也可以使用足够复杂的 shell 脚本)。但是 JShell 最适合用于调试和学习 java - 一个成熟的程序对于所有其他用例来说更加灵活。

JShell、.jsh 和java MyClass.java

JShell 是一个交互式 shell,用于尝试 java 代码。本质上,它是 Java 的 REPL

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

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

这允许使用单个命令从命令行快速执行单源文件,并且不会将其编译的类留在各处(不需要创建实际的临时目录,因为java 可以存储这些类在记忆中)。由于他们在java 中已经有 3 种其他执行模式(用于类、jar 文件和模块),因此将其添加为第四种并不是什么大问题。

既然 OP 想要一张照片:

Java 作为脚本语言

既然区别很明显(.jsh 用于 JShell,单源 java 可执行文件仅用于,您猜对了,单源 java 可执行文件),那么使用 Java 作为脚本语言呢?

您总是可以选择编写启动器;例如,

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

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

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

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

将其标记为可执行文件,然后从命令行启动它,就像您可以启动任何其他可执行文件一样。例如,将其复制并粘贴到 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 代码以供命令行使用将变得更加容易。

Java 仍然不是“脚本语言”(它永远不会与 Python 竞争),但是

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

【讨论】:

  • 这在 Mac 上的 openJDK 14 中似乎不起作用。我从 #! 之后的 / 得到“编译失败”。如果我删除了 shebang 行,那么直接在源文件上运行 java 就可以了。
  • @John Mac 可能对 java 可执行文件使用了不同的路径(因此“在尝试运行之前修复 jdk 位置”:-)
【解决方案2】:

当然,它仅限于在确定 IDE 和图形用户界面可以提供的范围方面带来一个正常的 REPL 实用程序。与单一源代码程序相比,我会更多地谈论它的功能。使其仍然与单一源代码程序区分开来的功能:

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

正如Single-File Source-Code Programs JEP 的替代品中所述:

我们可以将“一次性运行”的任务委托给jshell 工具。尽管 这乍一看似乎很明显,这是一个明确的非目标 jshell 的设计。

jshell 工具被设计成交互式 shell,许多设计决策都倾向于提供一个 更好的互动体验。

增加额外负担 成为批处理运行器的限制会减损 互动体验。


!!!限制和行为!!!

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

!!!功能等等!!!

更多关于链接的详细信息,使其优于单一文件源代码程序:

【讨论】:

    猜你喜欢
    • 2010-09-11
    • 2012-03-22
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 2011-08-01
    • 2011-01-24
    相关资源
    最近更新 更多