java -jar 是 Java 中运行可执行 JAR 包(Executable JAR)的核心命令,其底层依托 JVM 类加载机制、JAR 包规范和程序入口约定实现,核心逻辑是「JVM 解析 JAR 包元数据→加载指定主类→执行入口方法」,以下从核心前提、完整启动流程、关键细节、与普通启动的区别四方面彻底讲清原理,附实操验证和注意事项。
一、核心前提:可执行 JAR 包的特殊要求
java -jar 能启动的前提是JAR 包必须是「可执行 JAR」,普通依赖 JAR 包(仅含 class 文件,无启动配置)无法通过该命令运行。可执行 JAR 包的核心标识是:在 META-INF/MANIFEST.MF 文件中声明主类入口,这是 JVM 识别「启动类」的唯一依据。
1. 可执行 JAR 包的 MANIFEST.MF 核心配置
该文件是 JAR 包的「元数据清单」,java -jar 启动时会优先读取其中的 Main-Class 属性,格式要求严格(冒号后必须有 1 个空格,结尾无多余空行),示例:
Manifest-Version: 1.0
Main-Class: com.example.DemoApplication # 核心:指定程序入口主类(含全类名)
Class-Path: lib/commons-lang3-3.14.0.jar lib/fastjson2-2.0.32.jar # 可选:依赖的外部 JAR 包路径
Main-Class:必填,指定包含public static void main(String[] args)方法的主类(全类名,无.class后缀);Class-Path:可选,声明当前 JAR 包依赖的外部 JAR 包(相对路径,多个依赖用空格分隔,JVM 会按此加载依赖类);- 格式要求:属性名大小写固定,冒号
:后必须跟1 个空格,否则 JVM 会解析失败。
2. 普通 JAR 与可执行 JAR 的核心区别
| 类型 | 核心特征 | 启动方式 |
|---|---|---|
| 普通依赖 JAR | 仅含 class 文件,无 Main-Class | 无法 java -jar,仅作为其他项目的依赖被类加载 |
| 可执行 JAR | 含 Main-Class 声明,有主入口 | 直接 java -jar xxx.jar 启动 |
二、java -jar xxx.jar 完整启动流程(JVM 视角)
当在命令行执行 java -jar 命令时,JVM 会按固定步骤完成从「解析 JAR 包」到「执行 main 方法」的全过程,无额外手动干预,全程自动化,步骤如下(按执行顺序):
步骤 1:JVM 解析命令行参数,识别 -jar 标识
JVM 启动器(java.exe/java 可执行文件)首先解析命令行参数,当检测到 -jar 标识时,会触发 「JAR 包启动模式」,后续逻辑均围绕「加载并运行可执行 JAR 包」展开,同时忽略命令行中后续的其他类名参数(仅以 JAR 包为核心)。

