模块声明中的 requires 和 requires static 有什么区别?

28

在模块声明中,“requires”和“requires static”模块语句有什么区别?

例如:

module bar {
    requires java.compiler;
    requires static java.base;
}

3
可能是Java 9模块系统是否支持可选依赖项?的重复问题。 - ZhekaKozlov
1
@ZhekaKozlov 虽然我支持重复投票。但不太确定链接的帖子是否阐明了两者之间的区别。无论如何,我也相信这个问题背后的主要动机可能是想了解requires指令本身上的static修饰符。 - Naman
3
我不认为这是一个重复的问题。虽然这两个问题都涉及相同的主题,但它们有非常不同的角度。这个问题将被搜索语法的人找到,另一个问题则是由需要使依赖项可选的人找到的。 - Nicolai Parlog
2个回答

30

requires子句表示编译和运行时需要所需的模块。因此,当模块系统在模块分辨率期间(处理模块描述符并解析依赖项的阶段)遇到这样的子句时,它会搜索可观测模块的宇宙(JDK中的模块和模块路径上的模块),如果没有找到该模块则会抛出错误。

requires static子句表示运行时可选的依赖关系。这意味着在编译时,模块系统的行为与上述完全相同。

在运行时,它大多数情况下会忽略requires static子句。如果遇到一个,它不会解析它。也就是说,如果仅使用requires static引用可观测模块,则其不会进入模块图!这可能会有点令人惊讶。但是,如果模块以其他方式进入图形中(由某个其他模块要求,使用--add-modules手动添加,被服务绑定吸引),则所有具有对其可选依赖项的模块都可以进行读取


1
你能提供一些需要使用静态变量的用例吗?为什么我希望某些依赖项只在编译时存在? - gstackoverflow
1
我认为这超出了这个问题的范围,但我在我的博客文章关于可选依赖项中给出了两个例子。 - Nicolai Parlog

7
主要的区别在于,对于两者来说,情况不同。
requires static foo.module;

依赖关系在静态阶段(编译期)是强制性的,但在动态阶段(执行期)是可选的,另一方面

requires bar.module;

在编译时和运行时,通过名称声明模块依赖于其他模块。


你能提供一些需要使用static的实例吗?为什么我希望只在编译时存在某些依赖项? - gstackoverflow
5
Lombok和其他注解处理工具(例如非运行时注解)。 - Etki
@Etki请将此作为答案发布,我花了5分钟阅读了两个答案,只有通过您的评论才“明白了”。这已经是我在过去3年中第三次遇到这种情况了!拜托了... - Eugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接