20

在 Java 9 的模块声明中,有两种结构:

exports com.foo;

opens com.foo;

Whereexports授予编译时访问,而opens允许运行时访问,作为反射和资源。

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

open module com.mod {

但是没有类似的结构

exported module com.mod {

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

4

1 回答 1

19

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

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

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

于 2017-07-23T21:05:09.987 回答