news 2026/8/11 3:59:13

JAR 包详解:概念、结构、打包与依赖管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JAR 包详解:概念、结构、打包与依赖管理

一、生活化理解(先有个画面)

想象你要做一道“番茄牛腩面”:

  • 原材料:番茄、牛腩、面条、香料(分散的)

  • 打包好的方便面:面饼+调料包+脱水蔬菜,全在一个袋子里(JAR 包

  • 你只要拆开袋子,开水一泡就能吃(引入 JAR 包就能直接用)

JAR 包就是 Java 世界的“方便面”——它把一堆编译好的.class文件、配置文件、资源文件打包成一个文件,别人拿来就能用,不用自己从头炒料。

二、JAR 包的标准定义

JAR(Java Archive)是一种压缩文件格式,基于 ZIP 格式,用于聚合多个 Java 类文件、元数据和资源文件(图片、配置文件等)。

作用:

  1. 分发:把写好的功能打包发给别人。

  2. 复用:别人引入你的 JAR,就能调用里面的类和方法。

  3. 模块化:按功能拆分(如commons-lang.jar处理字符串,mysql-connector.jar连接数据库)。

三、JAR 包内部结构(打开看看)

用解压软件打开一个 JAR 包,通常看到:

text

my-app.jar ├── META-INF/ │ └── MANIFEST.MF # 清单文件(记录版本、主类等) ├── com/ │ └── example/ │ ├── Main.class # 编译后的字节码 │ └── Utils.class ├── config/ │ └── application.properties └── static/ └── logo.png
  • MANIFEST.MF很重要:可执行 JAR 会在这里指定Main-Class(入口类)。

四、怎么生成 JAR 包(带代码操作)

场景1:用jar命令手动打包

写两个简单类:

Calculator.java

java

package com.demo; public class Calculator { public int add(int a, int b) { return a + b; } }

MainApp.java

java

package com.demo; public class MainApp { public static void main(String[] args) { Calculator calc = new Calculator(); int result = calc.add(10, 20); System.out.println("Result: " + result); } }

编译

bash

javac -d . Calculator.java MainApp.java

(会在当前目录生成com/demo/*.class

打包成 JAR

bash

jar cvf my-app.jar com/
  • c创建

  • v显示详细

  • f指定文件名

执行 JAR(需要指定主类):

bash

java -cp my-app.jar com.demo.MainApp
场景2:制作“可执行 JAR”(双击运行)

写一个MANIFEST.MF文件:

text

Manifest-Version: 1.0 Main-Class: com.demo.MainApp

注意:最后必须有一个空行。

打包时把清单加进去:

bash

jar cvfm my-exec.jar MANIFEST.MF com/

运行:

bash

java -jar my-exec.jar

五、开发中最常见的用法:Maven/Gradle 管理依赖

现实项目中,几乎不用手动打包,而是用构建工具。

Maven 的pom.xml依赖片段

xml

<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency>

当你执行mvn compile,Maven 会自动从中央仓库下载commons-lang3-3.12.0.jar到本地~/.m2/repository/,并加入 classpath。

Gradle 的build.gradle

gradle

dependencies { implementation 'org.apache.commons:commons-lang3:3.12.0' }

六、代码里如何使用 JAR 包里的类

假设你引入了commons-lang3.jar,代码中直接 import:

java

import org.apache.commons.lang3.StringUtils; public class Demo { public static void main(String[] args) { // 判断字符串是否为空(来自 JAR 包) boolean empty = StringUtils.isEmpty(" "); System.out.println(empty); // false(因为空格不算空,如果用isBlank则true) // 反转字符串 String reversed = StringUtils.reverse("hello"); System.out.println(reversed); // olleh } }

编译运行时的 classpath 必须包含该 JAR

bash

javac -cp commons-lang3-3.12.0.jar Demo.java java -cp .:commons-lang3-3.12.0.jar Demo # Windows用分号;

七、JAR 包的“三大派系”

类型说明典型例子
普通 JAR只包含自己编译的类你的业务代码
可执行 JARMANIFEST.MF 指定了Main-Class,可用java -jar运行Spring Boot 打出的 fat jar
Fat JAR / Uber JAR把自己+所有依赖的三方 JAR 都解压再重新打包成一个超大 JARSpring Boot 微服务部署包

Spring Boot 的 Fat JAR 内部甚至还有BOOT-INF/lib目录存放依赖 JAR。

八、一个完整“打包-引用”实战(模拟真实协作)

步骤1:A 同学写工具类,打成 JAR 发给 B。

工具类DateUtil.java

java

package com.util; import java.time.LocalDate; public class DateUtil { public static String today() { return LocalDate.now().toString(); } }

打包:

bash

javac -d . DateUtil.java jar cvf date-util.jar com/

步骤2:B 同学拿到date-util.jar,复制到项目的lib/文件夹,然后引用:

B 的主程序App.java

java

import com.util.DateUtil; public class App { public static void main(String[] args) { System.out.println("Today is " + DateUtil.today()); } }

编译运行:

bash

javac -cp lib/date-util.jar App.java java -cp .:lib/date-util.jar App

九、常见面试/概念题

  1. JAR 和 WAR 的区别

    • JAR:普通 Java 应用或库

    • WAR:Web 应用归档,包含 WEB-INF/web.xml、JSP、Servlet 等,部署到 Tomcat/Jetty

  2. JAR 包冲突怎么解决

    • Maven 的dependency:tree查看依赖树

    • <exclusion>排除传递依赖

    • 或者升级/降级版本统一

  3. 怎么查看 JAR 包里的类

    bash

    jar tf my-app.jar # 列出所有文件 javap -cp my-app.jar com.demo.Calculator # 反编译查看方法签名

十、总结一句话

JAR 包 = Java 的压缩归档文件,是代码复用的基本单元,通过 classpath 引入,可以被构建工具自动管理,也可以手动打包分发。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/11 3:59:12

LangGraph核心原理与实战:基于图的工作流构建智能体系统

1. 从“链”到“图”&#xff1a;为什么我们需要 LangGraph&#xff1f;如果你在过去一年里折腾过 AI 应用开发&#xff0c;尤其是想搞点能自主决策、有状态的智能体&#xff08;Agent&#xff09;&#xff0c;那你大概率被 LangChain 的SequentialChain或者各种自定义循环逻辑…

作者头像 李华
网站建设 2026/8/11 3:58:27

基于SpringBoot的混合推荐系统架构与优化实践

1. 项目概述&#xff1a;图书推荐系统的技术架构与核心价值这个基于SpringBoot和推荐算法的图书推荐系统&#xff0c;是我在指导本科生毕业设计时反复验证过的成熟方案。不同于简单的增删改查系统&#xff0c;它完整实现了从用户行为采集、特征提取到个性化推荐的全流程闭环。系…

作者头像 李华
网站建设 2026/8/11 3:56:12

Vibe Coding时代:AI编程助手如何重塑生物信息学工作流

这次我们来看一个技术趋势讨论&#xff1a;Vibe Coding 时代下&#xff0c;传统生物信息学&#xff08;生信&#xff09;是否已经落幕。这不是一个具体的开源项目&#xff0c;而是一个关于开发范式、AI辅助编程与特定领域工作流变革的深度探讨。对于从事生物信息分析、数据科学…

作者头像 李华
网站建设 2026/8/11 3:56:07

C++队列与BFS算法:原理、实现与优化

1. 队列与广度优先搜索的核心概念解析在C算法领域&#xff0c;队列&#xff08;Queue&#xff09;和广度优先搜索&#xff08;BFS&#xff09;是两个紧密关联的核心概念。队列作为一种先进先出&#xff08;FIFO&#xff09;的数据结构&#xff0c;正是BFS算法得以实现的基础容器…

作者头像 李华
网站建设 2026/8/11 3:55:07

Python字符串转对象:从JSON到Document解析的三种实战场景

摘要开发中经常遇到"看起来像列表/对象的字符串"&#xff0c;怎么转成真正的Python对象&#xff1f;本文从三个场景展开&#xff1a;标准JSON字符串转列表、类列表字符串的安全解析、以及RAG项目中Document对象的元数据提取。读完即用。一、场景一&#xff1a;标准JS…

作者头像 李华