Почему не экспортируется весь модуль?

В декларации модуля Java 9 есть 2 конструкции:

exports com.foo;

И

opens com.foo;

Где exports предоставляет доступ во время компиляции, а opens обеспечивает доступ во время выполнения, как отражение и ресурсы.

opens имеет одну снисходительность над exports, что вы можете определить весь модуль как открытый, в результате получится так же, как явное открытие каждого пакета:

open module com.mod {

Но нет такой же конструкции

exported module com.mod {

Мой вопрос. Почему это так; какие решения были приняты, чтобы сразу открыть весь модуль, но не экспортировать?

Ответ 1

Экспорт модулей определяет его API, который должен быть продуманным и стабильным. "Экспортированный модуль" может легко и непреднамеренно изменять API, добавляя, удаляя или переименовывая пакеты, которые будут противоречить цели стабильности. (Это по сути по той же причине, почему нет "экспорта подстановочных знаков", например, exports foo.bar.*).

Открытые пакеты, с другой стороны, на самом деле не определяют API-интерфейс модуля. Конечно, код может зависеть от функциональности, доступной только через отражение, но сообщество Java обычно видит отражение как "взлома" при использовании для доступа к внутренним элементам.

Его гораздо более широкое (и более выгодное) использование - это доступ к артефакту для предоставления ему услуги (сериализация XML/JSON, настойчивость, инъекция зависимостей...). В таких случаях код, отражающий модуль, не зависит от него и, следовательно, не прерывается перемещением материала вокруг. Следовательно, существует меньше оснований для сохранения открытых пакетов, что делает возможным доступный для всех подход, такой как открытые модули.