30

我正在从What's New in Java9 中了解 Java 9 ,讨论中的热门话题之一是The Modular JDK

JAR 文件是模块吗?

模块与 JAR 文件有何不同?

4

3 回答 3

23

Module: A new language feature introduced in Java 9 (similar to class, interface, package, etc.) that consists of a collection of packages, similar to how a package consists of a collection of types.

JAR: An archive file format that bundles code and resources and which can be loaded by the JVM.

More specifically, a module is defined as follows:

In order to provide reliable configuration and strong encapsulation in a way that is both approachable to developers and supportable by existing tool chains we treat modules as a fundamental new kind of Java program component. A module is a named, self-describing collection of code and data. Its code is organized as a set of packages containing types, i.e., Java classes and interfaces; its data includes resources and other kinds of static information.

...

A module’s self-description is expressed in its module declaration, a new construct of the Java programming language.

...

A module declaration is compiled, by convention, into a file named module-info.class, placed similarly in the class-file output directory.

A module can be compiled into a Jar file, in which case the Jar file is labelled a modular Jar file:

Existing tools can already create, manipulate, and consume JAR files, so for ease of adoption and migration we define modular JAR files. A modular JAR file is like an ordinary JAR file in all possible ways, except that it also includes a module-info.class file in its root directory.

Some other differences between a module and a JAR:

  1. Modules can require other modules in order to allow accessing dependent classes by the requiring module. A Jar has no such dependency concept.

  2. A module can decide which classes and interfaces to export to other modules that require it. A Jar has no such encapsulation mechanism.

  3. A module can be compiled into a modular Jar file, but some modules (e.g. JDK modules) are compiled into another format called JMOD.

  4. The name of a JAR can be changed. As long as the JVM classloader finds the needed class on the classpath (which can be composed of a single JAR, multiple JARs, or a mix between directories or JARs), the name of the JAR file can be anything. However, the name of a module can be explicitly referenced in the declaration of other modules, and such the name defines it and cannot be changed freely.

于 2017-10-01T15:49:09.017 回答
13

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

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

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

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

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

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

于 2017-10-01T16:57:04.393 回答
12

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

不,Java Archive不是Module

举个例子,虽然同一个包的类可以分布在 JAR中,但现在不能从多个模块中读取同一个包。

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

另一方面(我也试过在这里描述这个〜>

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

这也包括在module-info.java.

每个模块定义要么

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

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

正如模块系统介绍的那样,模块化映像由模块而不是 JAR 文件组成。在模块化 WAR 文件方面,动态配置也可以预见模块化。


但是为了便于模块的采用,在 JDK9 中引入了一个模块化 JAR 文件,这样我们就可以说一个由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 文件。例如,上述的模块化 JAR 文件com.foo.bar module可能包含以下内容:

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 文件将被忽略。

于 2017-10-01T15:53:55.717 回答