JAR文件,即Java ARchive,是Java程序的一种集合打包形式。它可以包含编译后的类文件(.class
文件)、相关的元数据、资源文件(如文本、图片等)。
JAR文件实际上是ZIP文件的一种扩展,主要区别在于JAR文件可以包含一个META-INF/MANIFEST.MF
文件,用于指定类路径、版本信息及其他配置选项。
JAR文件的基本结构
一个典型的JAR包可以包含以下内容:
- 类文件(.class):编译后的Java源代码转换成的
.class
文件。 - 清单文件(META-INF/MANIFEST.MF):名为
MANIFEST.MF
的特殊文件,存放于META-INF
目录中,用于存储有关JAR文件的重要信息,如主类名称、依赖的类路径等。 - 其他JAR文件:嵌套的JAR文件,用于包含依赖。
- 资源文件:如图片、配置文件等非代码文件。
- 签名文件:如果JAR文件被数字签名,这些签名文件会存放在
META-INF
目录中。 - 其他元数据:如许可证文件、文档等。
JAR文件的类文件包路径
类文件包路径是JAR包组织和管理类文件的一种方式。它反映了Java源代码中的包结构,确保了类名的唯一性,并帮助Java虚拟机在运行时找到并加载正确的类文件。
包路径
包路径是相对于JAR文件根目录的路径,它对应于Java源代码中的package
语句。例如,如果一个Java类在源代码中声明为:
package cn.cengxuyuan.util;
包路径是类的全名的一部分,该类的包路径将是cn/cengxuyuan/util/
。
包路径定义了类的命名空间,用于组织和管理类。
JAR包中的类文件结构
在JAR包中,类文件的包路径被转换成文件系统的目录结构。这意味着每个package
语句都会在JAR文件内部创建一个相应的目录层次结构。以下是包路径与JAR文件内部结构的关系:
- 源代码包路径:
cn/cengxuyuan/util
- JAR文件内部结构:
META-INF/ cn/ cengxuyuan/ util/ MyClass.class
在这个例子中,MyClass.class
是编译后的类文件,它位于cn/cengxuyuan/util
包路径下。
默认情况下,如果没有指定访问修饰符,类、方法和字段默认为包私有。这意味着它们只能被同一个包中的其他类访问。
访问权限
Java提供了四种访问修饰符来控制类成员的可见性:
- public:声明为public的类、方法或字段可以从任何地方访问。
- protected:声明为protected的类成员可以被同一个包中的任何类访问,以及子类(即使子类在不同的包中)。
- default(无修饰符):没有指定访问修饰符的类成员默认为包私有,只能被同一个包中的类访问。
- private:声明为private的类成员只能被同一个类中的代码访问。
类文件的加载
当JAR包被加载到JVM时,类加载器会使用类文件的包路径来定位和加载这些类。以下是如何加载类文件的过程:
- 类全名:JVM通过类的全名来加载类,包括包路径和类名。例如,
cn.cengxuyuan.util.MyClass
。 - 转换为文件路径:类的全名中的点(
.
)被转换为文件系统中的路径分隔符(通常是斜杠/
)。 - 查找类文件:类加载器在JAR文件的相应目录中查找
.class
文件。
JAR文件的运行
当使用 java -jar
命令运行一个JAR文件时,Java虚拟机(JVM)会首先读取该JAR文件中的 META-INF/MANIFEST.MF
文件。这个文件定义了JAR包的一些元信息,包括主类(Main-Class)和其他属性。
在解析 MANIFEST.MF
文件后,JVM会查找并加载指定的主类。主类通常包含 public static void main(String[] args)
方法,这是Java程序的入口点。JVM使用类加载器加载主类后,调用其 main
方法,并将命令行参数传递给它。
主类的 main
方法负责驱动整个程序的执行。在执行过程中,主类可能会加载其他类和资源文件,这些类和资源文件也必须包含在JAR文件中或者可以通过CLASSPATH找到。
当所有指令执行完毕后,程序结束运行,JVM进程退出。如果需要后台运行,可以使用诸如 nohup java -jar XXX.jar &
的命令来使程序在后台持续运行,即使关闭控制台窗口也不会中断程序。
JAR文件的应用
类库封装
当多个类被多个项目共享时,将这些类打包成JAR文件提供给其他项目使用是非常普遍的做法。使用者只需将JAR文件添加到项目的CLASSPATH中,即可方便地引用其中的类和接口。例如,Apache cnmons库就提供了许多封装好的JAR包,供开发者使用。
在使用第三方jar包中的类时,需要添加引用或添加依赖才能正常import。常见的IDE如IntelliJ IDEA提供了便捷的导入方式,只需在Project Structure中添加jar包即可。此外,使用项目管理工具如Maven或Gradle,可以通过编辑pom.xml或build.gradle文件来添加外部JAR包依赖。
可执行JAR
通过在MANIFEST.MF
文件中指定Main-Class
属性,可以创建可执行的JAR文件。这样,用户只需使用java -jar
命令即可运行JAR文件,就像运行一个普通的Java程序一样。这大大简化了Java应用程序的部署过程。
对于可执行JAR文件,所有需要的依赖类和资源都需要被正确打包在内,以确保程序能够在没有外部依赖的情况下独立运行。
组件部署
很多Java应用支持通过加载JAR文件中的插件或组件来扩展功能。例如,许多Web服务器允许通过部署WAR(Web Application Archive)文件——一个特殊类型的JAR文件——来发布Web应用。这种机制使得应用的扩展性大大增强,同时也方便了功能的解耦和管理。
JAR文件还可以封装一些通用的功能模块,比如日志记录、数据库操作等,这样不同项目之间可以复用相同的模块,避免重复造轮子。
JAR和WAR的区别
JAR(Java Archive)文件和WAR(Web Application Archive)文件都是用于打包Java应用程序的归档文件格式。它们都是基于ZIP格式的,可以包含编译后的Java类文件、资源文件(如图片和配置文件等)、以及元数据信息。但是,它们在用途上有所区别:
JAR 文件
- 用途:JAR文件主要用于打包标准的Java类库或应用程序。它可以包含一个或多个Java类,以及这些类可能依赖的其他资源文件,比如属性文件、图标等。
- 结构:JAR文件通常包含一个
MANIFEST.MF
文件,该文件位于META-INF/
目录下,用于指定主类(如果JAR文件是一个可执行程序的话)和其他元数据信息。
WAR 文件
用途:WAR文件是专门用于打包Web应用程序的。它不仅包含了Java类文件,还包括了Web应用所需的静态资源(如HTML页面、CSS样式表、JavaScript脚本等),以及配置文件(如
web.xml
)。结构:WAR文件也有一个
MANIFEST.MF
文件,同样位于META-INF/
目录下。此外,WEB应用程序特有的配置文件web.xml
则位于WEB-INF/
目录下。这个文件定义了Servlet、过滤器、监听器等Web组件的配置信息。