Что такое открытый модуль в Java 9 и как его использовать
В чем разница между модулем с открытым ключевым словом до и без него?
Например:
open module foo {
}
module foo {
}
3 ответа
Чтобы обеспечить рефлексивный доступ к вашему модулю, Java 9 ввела ключевое слово open.
Вы можете создать открытый модуль, используя ключевое слово open в объявлении модуля.
Открытый модуль предоставляет отражающий доступ ко всем своим пакетам другим модулям.
Например, если вы хотите использовать какую-то инфраструктуру, которая в значительной степени зависит от отражения, например Spring, Hibernate и т. Д., Вы можете использовать это ключевое слово, чтобы включить рефлексивный доступ к нему.
Вы можете включить рефлексивный доступ для указанных пакетов вашего модуля, используя оператор открывания в объявлении пакета:
module foo {
opens com.example.bar;
}
или используя ключевое слово open в объявлении модуля:
open module foo {
}
но имейте в виду, что вы не можете объединить их:
open module foo {
opens com.example.bar;
}
результаты с ошибкой во время компиляции.
Надеюсь, поможет.
Немного предыстории к указанным директивам. Состояния модульной системы в разделе " Взлом инкапсуляции "
Иногда необходимо нарушить границы контроля доступа, определенные модульной системой и применяемые компилятором и виртуальной машиной, чтобы позволить одному модулю получить доступ к некоторым из неэкспортированных типов другого модуля. Это может быть желательно для того, чтобы, например, включить тестирование внутренних типов в "белой коробке" или предоставить неподдерживаемые внутренние API-интерфейсы для кода, который стал зависеть от них.
--add-exports
Для этого можно использовать параметр как во время компиляции, так и во время выполнения.
Параметр командной строки эквивалентен, например:-
module java.logging {
exports java.util.logging;
}
--add-exports
опция разрешает доступ к публичным типам указанного пакета.
Хотя после этого
Иногда необходимо пойти дальше и разрешить доступ ко всем непубличным элементам через метод setAccessible основного API-интерфейса отражения.
--add-opens
опция может быть использована во время выполнения, чтобы сделать это.
Эта опция командной строки эквивалентна, например:
module jdk.unsupported {
opens sun.misc;
}
Обычный именованный модуль, напротив, явно определен с объявлением модуля как:
module foo { }
и они известны как явные модули. Явные модули могут использовать директивы для пакетов, как указано выше, например, для export
/ open
пакеты, чтобы обеспечить рефлексивный доступ к их соответствующим публичным членам и классам.
С другой стороны, OPEN
модуль является
модуль, который не объявляет открытые пакеты, но полученный модуль обрабатывается так, как будто все пакеты открыты.
Таким образом, он предоставляет доступ во время выполнения к типам во всех пакетах модуля, как будто все пакеты экспортируются, что означает, что байт-код или отражение могут использоваться для доступа к классам или членам каждого пакета во всех пакетах. API отражения с setAccessible
или же MethodHandles.privateLookupIn
учитывайте глубокие размышления, так что вкратце вы можете размышлять над всеми членами всех классов во всех пакетах. Что также в значительной степени объясняет причину, по которой компилятор не допускает обе директивы open для пакета, пока модуль уже открыт.
Предположим, что 'foo' имеет два пакета: com.example и com.example.bar.
module foo {
opens com.example;
}
Вышеупомянутое объявление модуля разрешает рефлексивный доступ для типов внутри пакета com.example во время выполнения за пределами.
Но com.example не будет виден во время компиляции снаружи.
open module foo {
}
Это означает, что он неявно открывает все пакеты в модуле для среды выполнения для отражающего доступа.
Вышеупомянутый модуль declaratoin будет соответствовать следующему:
module foo {
opens com.example;
opens com.example.bar;
}