Java生态已经有两个强大的项目管理工具,Maven和Gradle,但缺少一个简单而强大的脚本工具。
这就是 JBang 发挥作用的地方。
它是一个简约但功能强大的 Java、Kotlin 和 Groovy 文件启动器。
事实上,它允许您像运行脚本一样轻松地运行代码。
它还提供许多其他功能,例如依赖管理、模板和 App Store。
让我们在这篇文章中探索 JBang 及其功能。
设置
jbang 命令行可以使用不同的方法安装在 Windows、Linux 和 macOS 上,这些方法在此处有详细记录。
我们可以通过运行 jbang --version 来验证安装。
除此之外,最好为我们最喜欢的 IDE 安装随附的 IDE 扩展。
此处列出了支持的 IDE 扩展。
JBang 不依赖于 JDK 到 JRE,但运行使用 Java 的脚本需要 JDK。
您可以通过运行 jbang jdk install 23 来安装 JBang,这将安装 JDK 23。
我们现在准备编写我们的第一个脚本。
第一个脚本
让我们创建一个简单的脚本来打印“Hello, World!”到控制台。
> jbang init helloworld.java
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
这将创建一个名为 helloworld.java 的文件,可以使用 jbang helloworld.java 运行。
> jbang helloworld.java
Hello world
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
当您打开该文件时,您将看到它是一个普通的 Java 文件,带有 main 方法和特定的第一行。
///usr/bin/env jbang "<pre class="brush:php;toolbar:false">> chmod +x helloworld.java
> ./helloworld.java
Hello world
登录后复制
登录后复制
登录后复制
登录后复制
" "$@" ; exit $?
import static java.lang.System.*;
public class helloworld {
public static void main(String... args) {
out.println("Hello world");
}
}
正如我们将看到的,JBang 脚本由三部分组成:shebang、可选属性和脚本本身。
我们将在接下来的部分中使用第二部分的一些属性,但让我们重点关注第一部分。
这部分 ///usr/bin/env jbang "$0" "$@" ;退出$?告诉系统使用 JBang 来运行脚本。
它在 Unix 生态系统中被称为 shebang,用于指定脚本的解释器。
我们可以在 Unix 系统(macOS、Linux)上通过运行 chmod x helloworld.java 使脚本可执行,然后运行 ./helloworld.java 来说明这一点。
/// usr/bin/env jbang "<pre class="brush:php;toolbar:false">///usr/bin/env jbang "<pre class="brush:php;toolbar:false">//JAVA 23+
//COMPILE_OPTIONS --enable-preview -source 23
//RUNTIME_OPTIONS --enable-preview
登录后复制
登录后复制
登录后复制
" "$@" ; exit $?
//JAVA 23+
//COMPILE_OPTIONS --enable-preview -source 23
//RUNTIME_OPTIONS --enable-preview
void main(String... args) {
System.out.println("Hello World");
}
" "$@" ; exit $?
//JAVA 25
//COMPILE_OPTIONS --enable-preview -source 25
//RUNTIME_OPTIONS --enable-preview
import java.util.concurrent.Callable;
import java.util.concurrent.StructuredTaskScope;
import static java.lang.System.*;
void main(String... args) {
out.println("Hello Java 25");
Callable
task1 = () -> {
out.println("Task 1" + Thread.currentThread());
return "Task 1";
};
Callable task2 = () -> {
out.println("Task 2" + Thread.currentThread());
return 2;
};
try (
var scope = new StructuredTaskScope