Что такое открытый модуль в Java 9 и как его использовать

в чем разница между модулем с открыть ключевое слово пока и без него?
Например:

open module foo {
}

module foo {
}

2 ответов


чтобы обеспечить отражающий доступ к вашему модулю, Java 9 представила открыть ключевое слово.

вы можете создать открытый модуль с помощью открыть ключевое слово в объявлении модуля.

An открыть модуль предоставляет отражающий доступ ко всем пакетам других модулей.

например, если вы хотите использовать некоторые рамки, которые сильно зависят от отражения, такие как Spring, Hibernate и т. д., Вы можете использовать это ключевое слово, чтобы включите отражательный доступ для него.

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

module foo {
    opens com.example.bar;
}

или используя ключевое слово open в объявлении модуля:

open module foo {
}

но имейте в виду, что вы не можете комбинировать их:

open module foo {
    opens com.example.bar;
}

результаты с ошибкой времени компиляции.

надеюсь, что это помогает.


немного предыстории директив в вопрос. The Система Модуль государства нарушение инкапсуляции раздел

иногда необходимо нарушать контроль доступа границы определяется системой модулей и применяется компилятором и virtual машина, для того чтобы один модуль для доступа к некоторым из неэкспортируется типы другого модуля. Это может быть желательно в чтобы, например,, включить тестирование внутренних типов в белом поле или предоставить неподдерживаемые внутренние API для кода, который стал зависеть от них. Этот --add-exports вариант можно использовать, на как время компиляции, так и время выполнения, чтобы сделать это.

параметр командной строки эквивалентен, например: -

module java.logging {
    exports java.util.logging;
}

на --add-exports опция включает доступ к открытым типам указанного пакета.


хотя после этого,

иногда необходимо пойти дальше и включить доступ ко всем непубличные элементы с помощью метода setAccessible ядра API рефлексии. The --add-opens опция может быть использована,во время, to сделать это.

этот параметр командной строки эквивалентны например:-

module jdk.unsupported  {
   opens sun.misc; 
}

обычный именованный модуль, напротив, определяется явно с объявлением модуля как:-

module foo { }

и они известны как явные модули. Явные модули могут использовать директивы для пакетов, как указано выше, например export/open пакеты для обеспечения отражающего доступа к их соответствующим публичным членам и классам.


С другой стороны,OPEN модуль

это не объявлять открытым пакеты но результирующий модуль обрабатывается так, как будто все пакеты открыты.

такой, что он предоставляет доступ во время выполнения к типам во всех пакетах модуля, как если бы все пакеты экспортировались, что означает, что байт-код или отражение могут использоваться для доступ к классам или членам каждого пакета во всех пакетах. Отражение APIs с setAccessible или MethodHandles.privateLookupIn разрешить глубокие размышления, так короче вы можете размышлять обо всех членах всех классов во всех пакетах. Что также в значительной степени объясняет причину, по которой компилятор не позволяет обе открытые директивы для пакета, пока модуль уже открыт.