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

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

exports com.foo; 

 opens com.foo; 

其中, exports授予编译时访问权限,而opens允许运行时访问,作为reflection和资源。

opensexports有一个宽容,你可以将整个模块定义为打开,结果与显式打开每个包相同:

 open module com.mod { 

但是没有类似的结构

 exported module com.mod { 

我的问题 :为什么会这样; 做出了哪些决定允许一次打开整个模块而不是出口?

模块的导出定义了它的API,应该有意设计并保持稳定。 “导出的模块”可能通过添加,删除或重命名包而轻易地且无意中更改其API,这将违背稳定性目标。 (这与exports foo.bar.* )没有“通配符导出”的原因基本相同。

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

它更广泛(也更有益)的用途是访问工件以为其提供服务(XML / JSON序列化,持久性,dependency injection……)。 在这种情况下,反映在模块上的代码不依赖于它,因此不会被移动的东西打破。 因此没有理由保持打开的软件包稳定,这使得像开放模块这样的免费方法变得可行。