模块和 JAR 文件之间有什么区别?

2022-09-01 08:49:19

我正在从Java9的新功能中学习Java 9,讨论中的热门话题之一是模块化JDK

JAR 文件是模块吗?

模块与 JAR 文件有何不同?


答案 1

模块:Java 9 中引入的一种新的语言特性(类似于类、接口、包等),它由一组包组成,类似于包由类型集合组成的方式。

JAR:一种归档文件格式,它捆绑了代码和资源,可以由 JVM 加载。

更具体地说,模块定义如下

为了提供可靠的配置和强大的封装,以一种既能为开发人员所接近又能得到现有工具链支持的方式,我们将模块视为一种基本的新型Java程序组件。模块是代码和数据的命名、自描述集合。它的代码被组织成一组包含类型的包,即Java类和接口;其数据包括资源和其他类型的静态信息。

...

模块的自我描述在其模块声明中表示,这是Java编程语言的一种新构造。

...

按照惯例,模块声明被编译成一个名为 的文件,该文件以类似方式放置在类文件输出目录中。module-info.class

模块可以编译成 Jar 文件,在这种情况下,Jar 文件被标记为模块化 Jar 文件

现有工具已经可以创建、操作和使用 JAR 文件,因此为了便于采用和迁移,我们定义了模块化 JAR 文件。模块化 JAR 文件在所有可能的方式上都类似于普通的 JAR 文件,只是它还在其根目录中包含一个文件。module-info.class

模块和 JAR 之间的一些其他区别:

  1. 模块可能需要其他模块,以便允许需要的模块访问依赖类。Jar 没有这样的依赖概念。

  2. 模块可以决定将哪些类和接口导出到需要它的其他模块。Jar 没有这样的封装机制。

  3. 一个模块可以编译成一个模块化的Jar文件,但一些模块(例如JDK模块)被编译成另一种称为JMOD的格式。

  4. 可以更改 JAR 的名称。只要 JVM 类装入器在类路径上找到所需的类(它可以由单个 JAR、多个 JAR 组成,或者由目录或 JAR 之间的混合组成),JAR 文件的名称可以是任何内容。但是,一个模块的名称可以在其他模块的声明中显式引用,并且这样的名称定义了它,并且不能自由更改。


答案 2

严格来说,模块是一个运行时概念。正如其他人从模块系统的状态中引用的那样:

模块是代码和数据的命名、自描述集合。它的代码被组织成一组包含类型的包,即Java类和接口;其数据包括资源和其他类型的静态信息。

这与 JAR 非常相似,但是...

  1. JAR 在运行时没有有意义的表示形式
  2. JAR不是“自描述的”,在这种情况下,这意味着它们没有JVM关心的名称,无法表达依赖关系或定义适当的API

这就留下了一个问题,模块来自哪里?有多种方法,但对于开发人员来说,最突出的一种是模块化JAR。模块化 JAR 就像普通的 JAR 一样,但它包含一个模块描述符,一个从 编译而来的文件。正是该文件定义了模块的名称、依赖项和 APImodule-info.classmodule-info.java

因此,JAR和模块之间存在很强的联系:JAR是模块系统创建模块的容器,并且(目前)每个JAR只能包含一个模块。重要的是要注意,即使在Java 9上,JAR也不必是模块化的 - 普通的JAR是完全没问题的。


推荐