为什么不允许导出整个模块?

在Java 9的模块声明中,有2个构造:

exports com.foo;

opens com.foo;

其中,授予编译时访问,同时允许运行时访问,作为反射和资源。exportsopens

opens有一个宽大处理,您可以将整个模块定义为打开,结果与显式打开每个包相同:exports

open module com.mod {

但是没有类似的结构

exported module com.mod {

我的问题:为什么会这样;已经做出了哪些决定来允许一次打开整个模块,但不允许导出?


答案 1

模块的导出定义了其API,该API应经过深思熟虑的设计并保持稳定。“导出的模块”可以通过添加,删除或重命名包来轻松无意中更改其API,这将违背稳定性目标。(这基本上与没有像“通配符导出”这样的原因相同)。exports foo.bar.*

另一方面,开放包并没有真正定义模块的API。当然,代码可以依赖于只能通过反射访问的功能,但是Java社区通常将反射视为用于访问内部的“黑客”。

它更广泛(更有益)的用途是访问工件以为其提供服务(XML / JSON序列化,持久性,依赖注入等)。在这种情况下,反映在模块上的代码不依赖于它,因此不会因移动内容而损坏。因此,保持打开的包稳定的理由更少,这使得像开放模块这样的免费方法成为可能。


答案 2

推荐