为什么包和模块是Java 9中的独立概念?


21

Java 9除了软件包外还将具有模块。通常,语言有其中一种。大多数程序员两个术语视为同义词。模块建立在包的顶部,将它们视为原语。复合模式建议对原始体和复合体进行统一处理。否则会发生不好的事情。例如,看一下Valhalla项目,他们尝试在其中尝试为基元(值)和引用类型改造通用超类型。

模块和包代表语义上独立的概念吗?这意味着对于任何一种语言都应同时使用(关注点分离)。还是Java必须兼具两者才能向后兼容?

为什么要引入新概念而不是增加现有概念?


JSR 376:在Jigsaw项目中实现的“ Java平台模块系统” 。

根据SOTMS

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

JLS小心地避免定义什么是。来自维基百科

Java软件包是一种将Java类组织到类似于Modula模块的名称空间中的技术,以Java提供模块化编程。

我知道引用Wikipedia是一种不好的做法,但它反映了大家的共识。从模块化编程入门

有时使用术语而不是模块(如Dart,Go或Java)。在其他实施方式中,这是一个独特的概念。在Python中,程序包是模块的集合,而在即将到来的Java 9中,计划引入新的模块概念(具有增强的访问控制的程序包的集合)。


3
我想您在这里一起问了很多问题?1)模块和包是否具有相同的语义概念?2)(如果不是1),jigsaw-style模块只是对软件包的技术改进吗?3)(如果不是1,如果是2),是Java只是(或表面上)保留两个概念以实现向后兼容。这些问题中有一些是可以回答的,有些主要是基于观点的。我认为,在此处进行简化所需的澄清的编辑是有必要的。
Tersosauros

1
@Tersosauros您已将“一些”问题归类为题外,但没有标记哪个是哪个。我认为这只是一个问题(1)。其他将自动解决。Java的向后兼容性不是问题。因此,无论是Java引入的修补补丁程序模块的设计缺陷,还是两个概念都是真正独立的问题。混乱归因于命名错误。
user2418306 '16

1
我想使问题更清楚。但是我需要了解您认为其中哪一部分是无法回答的。当我认为只有一部分时。
user2418306 '16

啊,我明白这个困惑。我认为问题#1 可以回答的(答案是“是,但不是”,这是问题#3出现的地方)。我对#3表示同意,显然Java不会更改像package/ does / means 这样的语言关键字,它们也不会更改为JRE中的类路径系统(让我们面对现实,这非常可怕)。问题2我觉得是主要是舆论导向的(它的交代,但我的回答和别人的可能不同,我们俩都必然是错误的)。
Tersosauros

1
尝试事先提出一个明确的问题,然后提供支持材料。
杰伊·埃尔斯顿

Answers:


22

模块的概念不同于该概念的实例化。

Java一直都有模块。方法是模块,类是包,包也是。模块是内部细节被隐藏的组织单位,并通过商定的合同与其他模块进行通信。例如,方法是模块,因为它具有隐藏的内部结构(代码和局部变量)和协定(参数和返回类型)。模块可以由低级模块组成,例如,类包含方法。

核心Java(9级之前)缺少的是可部署模块。上面所有类型的模块都是不可部署的单元,无法复制。Java确实有一个称为JAR文件的可部署构件,但是它们不是模块,因为它们没有封装或协定:在运行时JAR文件消失,所有文件合并为一个“类路径”。

OSGi在1998年以“捆绑”概念解决了缺乏可部署模块的问题。这些实际上是JAR文件,并且包含程序包,但是OSGi定义了其他元数据以及运行时系统,以支持该级别的封装和协定。

Java 9以类似于OSGi的方式解决了缺乏可部署模块的问题。可以说这完全没有必要,因为OSGi存在并且可以正常工作,但这是一个完全不同的讨论...

不幸的是,Java 9通过将新的模块概念仅命名为“模块”而感到困惑。这并不意味着方法,类和包不再是模块!J9“模块”只是模块概念的另一个实例。像OSGi包一样,J9模块也是由软件包组成的,它们是可以被复制的物理工件(通常是JAR文件)。运行时系统可以理解并优化它们。

简介:是的,J9模块和软件包在语义上是独立的概念。显然,为了向后兼容,Java必须保留其现有的软件包概念。注意,“包”一词在Java中的使用与在其他语言或包管理系统(如RPM)中完全不同。新的J9模块(和OSGi捆绑软件)比RPM中的软件包更像Java软件包。


包不符合您对模块的定义。由于封装较弱,并且缺乏聚合其他包装和改善其可见性的方法。类可以包含嵌套的类或字段。方法可以包含闭包或调用其他方法。程序包不能与其他程序包“通信”。
user2418306 '16

我不同意。程序包具有信息隐藏(默认访问类型,方法和字段,也称为程序包专用)。包肯定可以“通信”,因为包中的代码可以调用其他包中的代码。这是根据合同完成的,即另一包的公共类型和方法。
尼尔·巴特利特

注意,在同一级别聚集模块化工件(例如,包含闭包的方法,包含嵌套类的类)的能力并不构成我对模块的定义的一部分。如果您认为这是模块定义的必要部分,那么“ Java 9模块”也不是模块。
尼尔·巴特利特

我不否认软件包中隐藏了信息。我说那还不够。import可以组合包。但是没有办法将一揽子计划构造为头等公民。(OSGi的和限制)这些缺点在JSR 376描述
user2418306

您能否详细说明为什么Java 9模块也不是模块
user2418306 '16

10

让我冒险回答一下,尽管其中大部分可能是假设/头发分裂/刺痛等。

它们是一样的吗?好,不是

这篇有关“ Java 9中的模块化”的JavaWorld文章中

封装作为模块化解决方案

程序包尝试向Java编程环境添加抽象级别。它们为唯一的编码名称空间和配置上下文提供了便利。但是,令人遗憾的是,很容易规避软件包的约定,从而经常导致危险的编译时耦合环境。

正如@ user2418306(OP)所暗示的,模块是正确完成的软件包。Java(显然是Java 9)的模块和包在语义上是一样的(正如OP所要求的)。也就是说,它们是预编译的JVM字节码以及其他元数据的集合- 本质上讲,它们是

那么有什么区别呢?

但是,不同之处在于它们每个内部的元数据。Java package清单或JAR清单通常不是由库开发人员维护的,它们也不提供关于JAR /程序包所提供内容的任何确定的合同。如此处所解释(再次JavaWorld文章)

JAR文件不够模块化吗?

JAR文件及其运行所在的部署环境在许多以前可用的旧式部署约定上得到了极大的改善。但是,除了很少使用的版本号(隐藏在.jar清单中)之外,JAR文件没有固有的唯一性。JAR文件和可选清单未在Java运行时环境中用作模块化约定。因此,文件中类的包名称及其在类路径中的参与是JAR结构中唯一为运行时环境提供模块化的部分。


关于其他语言/环境等的怒吼

该文章讨论的另一个领域是Maven之类的系统,它们在构建过程中为您管理依赖项。从Apache Maven网站上的此页面

依赖管理:

Maven鼓励使用JAR和其他依赖项的中央存储库。Maven带有一种机制,您的项目的客户可以使用该机制从中央JAR存储库中下载构建项目所需的任何JAR,就像Perl的CPAN一样。这使Maven的用户可以在项目之间重用JAR,并鼓励项目之间进行通信,以确保解决向后兼容性问题。

现在谈论未来,好像我去过那里一样

该页面所述,其他语言(例如Perl)具有程序包存储库(例如CPAN)。在过去约十年的时间里,这是一个不断增长的趋势(我说是因为我觉得自己没有任何证据)。诸如Ruby的gems,Python的PyPiNode包管理器(npm)之类的工具就以此为基础,从而提供了一种一致的方式来配置具有正确内容(包,模块,宝石,小发明等)。一个想法(我觉得)是借来的从Linux发行版系统,如Debian的贴切,RedHat的rpm等等(虽然很明显,已经演变至少一个世代,并取得了这些东西都更好。)


Java的模块,虽然他们不一定添加任何东西,你已经不能做什么,工装依赖性/包管理和自动化构建环境中的所有MUCH更容易。我拒绝说这是否使模块“更好”。:P


1
文章只有1岁,但是已经过时了。它详细说明了版本控制是模块的基本特征。拼图模块将没有版本信息。对于最终用户,依赖关系管理的任何方面都不会改变。实际上,对于构建工具而言,事情将变得更加困难。因为他们需要支持classpath和的并行现实modulepath。并跳过障碍以支持单元测试。前提是两个概念是等效的,因为它们表示事物的集合以及元数据对于我来说太大胆了。再加上中间,您突然用jar代替了包装。
user2418306 '16

我不是说“ 两个概念是等效的 ”,而是说它们“在语义上是同一件事”,这就是您要问的。此外,您编辑,因为我回答这个问题特别提及JSR-376,作为反对拼图这是我们前面说: - /
Tersosauros

拼图包含(实现)JSR-376。问题仍然与两者相关,因此没有造成任何伤害。字典将等效定义为具有相同含义的质量或状态。并且在语义上-关于意义。抱歉,您在这里对错误的详细信息感到厌倦。您已经说过它们是等效的。但是您没有提供任何推理。取而代之的是,您参考的文章解释了软件包和jar如何成为模块。但是即将发布的模块也不能成为本文的模块。声明对等然后在2(3)之间提供差异是自相矛盾的。
user2418306 '16

问题的答案不能为是和否。两个概念在语义上是否相等。请不要偏my我的评论,然后返回原始问题。语言是否需要两个概念,或者这是Java遗留问题?如果您需要澄清,我们很乐意为您提供帮助。
user2418306 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.