- 编译:将
.java源代码文件编译成.class字节码文件。 - 打包:将
.class文件和其他资源(如图片、配置文件)打包成一个.jar文件。
准备工作:一个简单的 Java 项目
为了演示,我们先创建一个简单的项目结构,假设我们有一个 HelloWorld 类和一个 Greeter 类。

项目目录结构:
my-project/
├── src/
│ ├── com/
│ │ └── example/
│ │ ├── Greeter.java
│ │ └── HelloWorld.java
└── lib/ (如果需要依赖第三方库,可以放在这里)
Greeter.java (一个辅助类)
// src/com/example/Greeter.java
package com.example;
public class Greeter {
public String sayHello(String name) {
return "Hello, " + name + "!";
}
}
HelloWorld.java (主类,包含 main 方法)
// src/com/example/HelloWorld.java
package com.example;
public class HelloWorld {
public static void main(String[] args) {
Greeter greeter = new Greeter();
String message = greeter.sayHello("from Command Line");
System.out.println(message);
}
}
第一步:编译 .java 文件
我们将使用 javac 命令来编译源代码。

打开命令行/终端
- Windows: 打开
cmd或PowerShell。 - macOS / Linux: 打开
Terminal。
进入项目目录
切换到你的项目根目录 my-project。
cd /path/to/your/my-project
执行编译命令

最关键的一点是,javac 需要知道你的源代码在哪里,我们使用 -d 选项来指定编译后的 .class 文件的输出目录。
# 命令格式: javac -d <输出目录> <源代码文件或目录> # -d . 表示将 .class 文件输出到当前目录,并按照包结构创建子目录 javac -d . src/com/example/*.java
命令解释:
javac: Java 编译器命令。-d .:-d选项用于指定放置生成的类文件的目录。 表示当前目录(即my-project),编译后,会自动根据package语句创建com/example/这样的子目录结构。src/com/example/*.java: 要编译的源文件。 是通配符,表示编译src/com/example/目录下所有的.java文件。
编译成功后,你的目录结构会变成这样:
my-project/
├── src/
│ └── com/
│ └── example/
│ ├── Greeter.java
│ └── HelloWorld.java
├── com/ <-- 新生成的目录
│ └── example/
│ ├── Greeter.class
│ └── HelloWorld.class
└── lib/
com/example/HelloWorld.class 就是我们的可执行字节码文件。
第二步:打包 .jar 文件
现在我们使用 jar 命令将编译好的 .class 文件打包成一个 JAR 文件。
执行打包命令
我们仍然在 my-project 目录下执行命令。
# 命令格式: jar -c -f <jar文件名> -C <目录> . # 为了方便,我们通常将常用选项组合在一起 jar -cvf my-app.jar -C com .
命令解释:
jar: Java 打包工具命令。-c: 创建一个新的 JAR 文件 (create)。-v: 生成详细输出,在控制台显示正在打包的文件 (verbose),这个选项是可选的,但有助于确认过程。-f: 指定 JAR 文件的名称 (file),紧跟-f的是你想要的 JAR 文件名,这里是my-app.jar。-C com .: 这是非常重要的一步。-C选项用于在创建 JAR 文件之前,临时切换到指定的目录。com是我们存放.class文件的根目录。- (点号) 表示从当前切换到的目录(即
com目录)开始,将其打包进 JAR 文件,这确保了 JAR 文件内部的路径结构是正确的(com/example/HelloWorld.class)。
执行成功后,你的目录结构会变成:
my-project/
├── src/
│ └── com/
│ └── example/
│ ├── Greeter.java
│ └── HelloWorld.java
├── com/
│ └── example/
│ ├── Greeter.class
│ └── HelloWorld.class
├── lib/
└── my-app.jar <-- 新生成的 JAR 文件
第三步:运行 JAR 文件
一个普通的 JAR 文件,系统并不知道哪个类是入口点,我们需要在创建 JAR 时指定一个 Main-Class。
使用 manifest 文件(推荐)
创建 manifest 文件
创建一个名为 MANIFEST.MF 的文本文件,内容如下:
# MANIFEST.MF
Main-Class: com.example.HelloWorld
注意:
Main-Class:后面有一个空格。- 类名必须是完整的、带包名的类名。
- 文件末尾需要有一个空行,这在某些版本中是必须的。
重新打包 JAR 文件
使用 m 选项将 manifest 文件包含进去。
jar -cvfm my-app.jar MANIFEST.MF -C com .
命令解释:
-m: 指定manifest文件 (manifest)。-f: 指定 JAR 文件名。my-app.jar: JAR 文件名。MANIFEST.MF: manifest 文件名。-C com .: 和之前一样,打包com目录下的所有内容。
直接在命令行指定(更简单)
对于简单的项目,可以直接在 jar 命令中使用 e 选项来指定入口点,无需创建 MANIFEST.MF 文件。
jar -cvef my-app.jar com.example.HelloWorld -C com .
命令解释:
-e: 指定程序的入口点类 (entry)。my-app.jar: JAR 文件名。com.example.HelloWorld: 完整的入口点类名。-C com .: 打包com目录下的所有内容。
运行 JAR 文件
你可以使用 java 命令来运行这个 JAR 文件了。
# 命令格式: java -jar <jar文件名> java -jar my-app.jar
预期输出:
Hello, from Command Line!
高级主题:处理外部依赖
如果你的项目依赖了第三方库(commons-lang3.jar 放在 lib 目录下),编译和打包过程会更复杂一些。
编译时包含依赖
javac 需要依赖的 JAR 文件来进行编译,使用 -cp (classpath) 选项。
# Windows 下路径分隔符是 ; javac -d . -cp "lib/commons-lang3.jar" src/com/example/*.java # Linux / macOS 下路径分隔符是 : javac -d . -cp "lib/commons-lang3.jar" src/com/example/*.java
打包时包含依赖
标准的 jar 命令无法将其他 JAR 文件“解压”后打包进去,你需要一个更强大的工具,最常用的是 Maven 或 Gradle,但如果必须用命令行,可以这样做:
# 先创建一个临时的 JAR,只包含你的代码 jar -cvf my-app-internal.jar -C com . # 然后使用 `jar` 命令将所有 JAR 合并 # 注意:这种方法会将依赖 JAR 作为独立的文件放在 JAR 中,Java 默认不会加载它们。 # 真正需要的是将依赖解压后与你的代码一起打包,这很繁琐。 # 更实际的做法是使用 `zip` 命令(在 Linux/macOS 上)或第三方工具 # 在 Linux/macOS 上: zip -r my-app-with-deps.jar my-app-internal.jar lib/commons-lang3.jar
重要提示:处理复杂依赖时,强烈建议使用 Maven 或 Gradle 等构建工具,它们能自动处理依赖下载、编译、打包和生成可执行 JAR 等所有繁琐的步骤。
| 步骤 | 命令 | 说明 |
|---|---|---|
| 编译 | javac -d . src/com/example/*.java |
将 .java 文件编译成 .class 文件,并按包结构输出。 |
| 打包 | jar -cvfm my-app.jar MANIFEST.MF -C com . |
将 .class 文件打包成 JAR,并通过 MANIFEST.MF 指定主类。 |
| 运行 | java -jar my-app.jar |
运行带有主类的可执行 JAR 文件。 |
掌握这个流程能帮助你理解 Java 程序从源代码到可执行文件的完整生命周期,即使在实际开发中更多地使用 IDE 和构建工具,这些底层知识也至关重要。
