1. 概述
一个有意义的 Java 应用通常会依赖一个或多个 JAR 包。但在某些场景下,JAR 文件本身就是一个完整的独立应用(Standalone Application)或 Web 应用。
本文我们聚焦在 独立应用 的运行方式上。我们将学习如何创建一个 JAR 应用,并掌握如何在命令行中带参数或不带参数运行它。
2. 创建一个 JAR 应用
一个 JAR 文件中可以包含多个 main 类(main class),每个 main 类都可以作为程序的入口点。✅ 也就是说,理论上一个 JAR 文件可以包含多个应用,但至少要有一个 main 类才能被运行。
如果 JAR 文件的 MANIFEST.MF 文件中指定了 Main-Class,那这个 JAR 就是一个可执行 JAR(Executable JAR)。这个 main 类必须包含在该 JAR 中。
下面是一个使用 javac
编译 Java 类,并通过指定 MANIFEST 文件创建可执行 JAR 的示例:
$ javac com/baeldung/jarArguments/*.java
$ jar cfm JarExample.jar ../resources/example_manifest.txt com/baeldung/jarArguments/*.class
一个 非可执行 JAR 就是未在 MANIFEST 文件中定义 Main-Class 的 JAR。我们仍然可以运行其中的 main 类,只是运行方式略有不同。
创建一个非可执行 JAR 的命令如下:
$ jar cf JarExample2.jar com/baeldung/jarArguments/*.class
3. Java 命令行参数
和普通应用一样,JAR 应用也支持接收命令行参数,参数数量可为零或多个,具体取决于应用需求。
使用命令行参数可以让用户在启动时传入配置信息,从而避免硬编码,提升灵活性和通用性。
参数中可以包含字母、数字、Unicode 字符,以及一些 shell 允许的特殊字符(如 @)。参数之间通过空格分隔。如果某个参数本身包含空格,需要用引号包裹,单引号和双引号都可以。
Java 程序的入口是 main 方法,所有参数都会以 String[]
的形式传入。我们可以根据需要将其转换为其他类型(如 int
, double
等)。
4. 运行可执行 JAR 并传参
运行可执行 JAR 的基本语法如下:
java -jar jar文件名 [参数列表...]
我们前面创建的可执行 JAR 是一个简单的应用,它会打印传入的参数。可以传入任意数量的参数。
示例:
$ java -jar JarExample.jar "arg 1" arg2@
输出如下:
Hello Baeldung Reader in JarExample!
There are 2 argument(s)!
Argument(1):arg 1
Argument(2):arg2@
✅ 注意:运行可执行 JAR 时,不需要在命令行中指定 main 类名,参数直接写在 JAR 文件名后面即可。如果你误加了类名,它会被当作第一个参数传入 main 方法。
虽然一个可执行 JAR 只能在 MANIFEST 中指定一个 main 类,但我们可以手动运行其他 main 类,就像运行非可执行 JAR 一样,详见下一节。
5. 运行非可执行 JAR 并传参
运行非可执行 JAR 时,不能使用 -jar
,而是要用 -cp
(即 classpath)来指定类路径:
java -cp jar文件名 主类名 [参数列表...]
✅ 注意:这种情况下必须显式指定 main 类名,参数跟在类名之后。
我们前面创建的非可执行 JAR 同样包含那个简单的打印参数应用。示例如下:
$ java -cp JarExample2.jar com.baeldung.jarArguments.JarExample "arg 1" arg2@
输出结果与之前一致:
Hello Baeldung Reader in JarExample!
There are 2 argument(s)!
Argument(1):arg 1
Argument(2):arg2@
⚠️ 踩坑提醒:类名要写全限定名(含包名),否则会报错 Could not find or load main class
。
6. 小结
本文我们介绍了两种运行 JAR 应用的方式:
类型 | 启动方式 | 是否需要指定 main 类 |
---|---|---|
可执行 JAR | java -jar JarExample.jar [args...] |
❌ 不需要 |
非可执行 JAR | java -cp JarExample2.jar com.baeldung.jarArguments.JarExample [args...] |
✅ 需要 |
我们还演示了如何传递带空格和特殊字符的参数,并强调了 main 方法接收参数的方式。
无论哪种方式,只要掌握了命令行参数的处理逻辑,就能灵活地控制 Java 应用的启动行为。