当前位置: 首页 > 知识库问答 >
问题:

在Java9中,需要和需要传递语句有什么区别?

岳刚洁
2023-03-14

在模块声明中,requires和requires可传递模块语句之间有什么区别

例如:

module foo {
    requires java.base;
    requires transitive java.compiler;
}

共有3个答案

麻和雅
2023-03-14

要求描述了模块之间相互依赖的解析过程。

引用行

要求指令(与传递无关)表示一个模块依赖于其他模块。传递修饰符的作用是使其他模块也依赖于其他模块。如果模块M需要传递N,那么M不仅依赖于N,任何依赖于M的模块也依赖于N。这允许M被重构,以便它的一些或所有内容可以移动到一个新的模块N,而不会中断具有“需要M”指令的模块。

简言之:

需要-M模块依赖于其他模块N。

需要可传递的-其他模块隐式依赖于其他模块。例如:如果M模依赖于N,而另一个模P依赖于M,那么它也隐式依赖于N。

汪弘毅
2023-03-14

这两者之间的主要区别在于从一个模块到另一个模块的访问。

如果一个模块导出一个包,该包包含一个类型,该类型的签名引用第二个模块中的包,那么第一个模块的声明应包括对第二个模块的requires transitive依赖。这将确保依赖于第一个模块的其他模块能够自动读取第二个模块,从而访问该模块导出包中的所有类型。

因此,让我们假设您的用例:-

module foo {
    requires java.base;
    requires transitive java.compiler;
}

~

~

module bar {
    requires foo; // java.compiler is available to read
    requires java.base; // still required
}
穆英飙
2023-03-14

如果模块条形码需要模块饮料,则模块系统。。。

  • 强制饮料的存在(称为可靠配置)

如果条形码要求可传递的饮料,也会发生同样的情况-饮料必须存在,可以读取和访问。事实上,对于酒吧和饮料来说,transitive关键字没有任何改变。

依赖于bar的模块是受传递影响的模块:任何读取bar的模块也可以读取饮料。换句话说,饮料的可读性是隐含的(这就是为什么这被称为隐含可读性)。结果是顾客可以获得饮料的类型。

所以,如果bar需要可传递的饮料,而客户需要bar,则客户可以阅读饮料,即使它并不明确依赖于它。

但是为什么呢?假设您有一个模块,其公共API接受或返回另一个模块的类型。假设bar模块公开返回饮料的实例,这是来自饮料模块的接口:

// in module _bar_
public class Bar {

    // `Drink` comes from the module _drink_,
    // which _bar_ requires
    public Drink buyDrink() { /* ... */ }

}

在本例中,酒吧使用常规的requires饮料。比如说,客户依赖于酒吧,所以其所有代码都可以调用bar::buydread。但是当它发生时会发生什么呢?

模块系统投诉客户未阅读饮料,因此无法访问饮料。要解决这个问题,客户还必须依赖饮料。真烦人!一个你不能马上使用的酒吧有多没用?

出于这个原因,引入了隐含的可读性:使一个在自己的公共应用编程接口中使用另一个模块类型的模块立即可用,而不需要调用者寻找并要求所有相关的模块。

所以如果酒吧需要传递饮料,顾客可以开始购买饮料,而不必需要饮料-需要酒吧就足够了。因为它应该。

 类似资料:
  • 问题内容: 我目前正在将SQL Server SQL语句转换为它们的ANSI泛型等效项,并且使用WITH语句来限制递归语句。 为了专注于此问题,我将简化如下的问题 如果我有两张桌子 报告单位 col1:密钥 col2:ParentReportingUnitKey 设施 col1:密钥 col2:ParentReportingUnitKey 此结构描述了直至设施的报告单位的层次结构,其中报告单位可以

  • 问题内容: 我是一名Android开发人员,最近遇到了SQLite中的GLOB子句。考虑到LIKE已经到位,我不明白为什么我们需要GLOB。 这两个子句都有通配符来表示单个和多个字符。唯一的区别是GLOB区分大小写。 但是,这就是全部吗?是否有任何疑问是LIKE不好或不合适的选择?在任何情况下,我们绝对必须使用GLOBE vs LIKE,反之亦然? 问题答案: 区分大小写本身是有用的,因为它与常规

  • 我正在学习异步/等待,在阅读本文之后,不要阻塞异步代码 这是异步/等待适合于 IO 和 CPU 绑定的方法 我注意到@Stephen Cleary文章中的一个提示。 使用ConfigureAwait(false)避免死锁是一种危险的做法。您必须对阻塞代码调用的所有方法(包括所有第三方和第二方代码)的传递闭包中的每个等待使用ConfigureAwait(false)。使用ConfigureAwait

  • 我读了一些关于如何使用log4j的文章。他们中的大多数给出以下代码作为开始: 或 这将初始化记录器对象。但是我的问题是为什么需要发送类类型作为参数?似乎当我使用记录器时,我不在乎在哪个类中使用它。所以类类型似乎对记录器没有影响。如果我声明一个记录器为静态和公共的,我可以在另一个类中调用这个记录器,那么作者这样设计它的意图是什么?当我使用记录器时,类类型会绑定一些东西吗?或者我可以发送任何类类型到g

  • 问题内容: 我已经浏览了网络上的大多数论文,但是我仍然无法理解为什么我们必须使用向上转换。 您可以考虑使用此示例进行上播。这里的向上转换有什么用?两者并给出相同的输出! 问题答案: 在大多数情况下,完全没有必要进行明确的插播,也没有任何效果。 在您的示例中,显式上行 可以替换为: 隐式转换(用于Java对象类型)的目的是“忘记”静态类型信息,以便具有特定类型的对象可以在需要更通用类型的情况下使用。