【问题标题】:What is the difference between modules and JAR files?模块和 JAR 文件有什么区别?
【发布时间】:2017-10-01 15:29:55
【问题描述】:

我正在从 What's New in Java9 学习 Java 9,讨论中的热门话题之一是 模块化 JDK

JAR 文件是模块吗?

模块与 JAR 文件有何不同?

【问题讨论】:

标签: java jar java-9 java-module


【解决方案1】:

Module:Java 9 中引入的一种新的语言功能(类似于类、接口、包等),由包的集合组成,类似于如何一个包由一组类型组成。

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

更具体地说,一个模块是defined as follows

为了提供可靠的配置和强大的封装,让开发人员可以使用并且现有工具链可以支持,我们将模块视为一种基本的新型 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 文件的名称可以是任何名称。但是,一个模块的名称可以在其他模块的声明中显式引用,这样的名称定义了它,不能随意更改。

【讨论】:

  • A module is a named, self-describing collection of code and data,JAR 文件也是如此,对吧? JAR 有一个名字,它是自包含和代码的集合。
  • @NeerajJain 是的,但 JAR 不是语言或 JVM 元素。此外,它没有“要求”其他 JAR 或为其包含的代码提供访问控制的概念。将模块视为类似于包,但它不包含类和接口,而是包含其他模块可以访问或不可以访问的包。
【解决方案2】:

严格来说,模块是一个运行时概念。正如其他人从The State of the Module system 引用的那样:

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

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

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

这就留下了一个问题,模块从何而来?有多种方法,但对开发人员来说最突出的一种是模块化 JAR。 模块化 JAR 与普通 JAR 一样,但它包含一个 模块描述符,即从 module-info.java 编译的文件 module-info.classdefines a module's name, dependencies, and APIs就是那个文件。

所以 JAR 和模块之间有很强的联系:JAR 是模块系统从中创建模块的容器,并且(目前)每个 JAR 只能包含一个模块。需要注意的是,即使在 Java 9 上,JAR 也必须是模块化的 - 普通的 JAR 完全可以。

【讨论】:

  • 非常好,易于理解的描述。可以补充一点,普通的非模块化 JAR 也会被 ModuleFinder 自动解释为一个模块。
  • 您引用的是自动模块,对吗?如果我讨论它们,我还应该进入平台和系统模块,这似乎有点太详细了。如果您想在自己的答案中深入了解(并告诉我),我会从这里链接。
【解决方案3】:

JAR 文件是模块吗? Module 与 JAR 文件有何不同?

不,Java Archive 不是模块

仅举个例子,虽然 the same package could have been spread across JARs 的类,同一个包现在 can not be read from multiple modules.

JAR 是一种文件格式,可让您捆绑多个文件 到单个存档文件中。通常这包含类文件 以及与小程序和应用程序相关的辅助资源。

另一方面(我试着在这里描述这个~>

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

这还包括在module-info.java 的帮助下指定的模块声明。

每个模块定义都是

  • 模块工件,即包含已编译模块定义的模块化 JAR 文件或 JMOD 文件,否则

  • 一个 exploded-module 目录,按照惯例,它的名称是模块的名称,其内容是对应于包层次结构的“exploded”目录树。

    李>

正如在模块系统中介绍的那样,模块化映像由模块而不是 JAR 文件组成。 根据Modular WAR file as well.,动态配置可预见模块化


但是为了便于采用 Modules,在 JDK9 中引入了 Modular JAR file,,例如,对于由 module-info.java 组成的模块,

module com.foo.bar { }

和其他java类一样

com/foo/bar/alpha/AlphaFactory.java
com/foo/bar/alpha/Alpha.java

现有工具已经可以创建、操作和使用 JAR 文件。 模块化的 JAR 文件就像一个普通的 JAR 文件一样 可能的方法,除了它还包含一个 module-info.class 文件 在其根目录中。例如,上述com.foo.bar module 的模块化 JAR 文件可能包含以下内容:

META-INF/
META-INF/MANIFEST.MF
module-info.class
com/foo/bar/alpha/AlphaFactory.class
com/foo/bar/alpha/Alpha.class
...

模块化 JAR 文件可以用作模块,在这种情况下,它的 module-info.class 文件被用来包含模块的声明。 或者,它可以放在普通的类路径上,其中 如果它的 module-info.class 文件被忽略。

【讨论】:

    猜你喜欢
    • 2011-09-16
    • 2011-08-28
    • 2017-02-25
    • 2011-04-10
    • 2013-01-11
    • 2015-11-25
    • 1970-01-01
    相关资源
    最近更新 更多