回答更新后的问题
所有问题都可以使用 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 循环
- 您可以更轻松地执行短程序