Ответ 1
Да, поддерживаются дополнительные зависимости. Цитата из исходное предложение:
Расширьте язык деклараций модуля, чтобы модификатор
static
использовался в директивеrequires
со следующими значениями:
Во время компиляции
requires static M
выражает обязательную зависимость. Это ошибка, если подходящий модуль не может быть найден среди наблюдаемых модулей и разрешен.В фазах после времени компиляции
requires static M
выражает необязательную зависимость. Система модуля не будет искать наблюдаемые модули для подходящего модуля во время разрешения, но если итоговый графа модуля содержит подходящий модуль, он добавит соответствующий край читаемости перед выполнением обычных проверок здравобезопасности после разрешения. [...]Таким образом, гипотетическое объявление модуля формы
module joda.beans { requires static joda.collect; ... }
гарантирует, что модуль
joda.collect
доступен во время компиляции, поэтому код в модулеjoda.beans
, который ссылается наjoda.collect
, может быть скомпилирован без каких-либо проблем. Тем не менее, он не гарантирует, чтоjoda.collect
доступен во время соединения или времени выполнения.
(Тем временем для этой функции была создана официальная документация .)
Я написал демо для этого. Интересными примерами являются module-info.java
модуля, объявляющие необязательные зависимости...
module org.codefx.demo.advent {
// list the required modules
requires org.codefx.demo.advent.calendar;
// with 'static' the factories are only required at compile time;
// to be present at run time either other modules most require them
// or they must be added with the '--add-modules' command line option
requires static org.codefx.demo.advent.factory.chocolate;
requires static org.codefx.demo.advent.factory.quote;
}
... и код в том же модуле, который хочет получить доступ к типам из своих необязательных зависимостей. Он должен быть написан так, что он терпит неудачу, если отсутствуют типы ChocolateFactory
и/или QuoteFactory
:
private static List<SurpriseFactory> createSurpriseFactories() {
return Stream.of(
createChocolateFactoryIfAccessible(),
createQuoteFactoryIfAccessible())
.flatMap(Optional::stream)
.collect(toList());
}
private static Optional<SurpriseFactory> createChocolateFactoryIfAccessible() {
try {
return Optional.of(new ChocolateFactory());
} catch (NoClassDefFoundError er) {
return Optional.empty();
}
}
private static Optional<SurpriseFactory> createQuoteFactoryIfAccessible() {
try {
return Optional.of(new QuoteFactory());
} catch (NoClassDefFoundError er) {
return Optional.empty();
}
}
Наконец, командную строку можно использовать для определения того, какие модули запускаются приложением:
$java \
--add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote \
-p mods -m org.codefx.demo.advent
Конечно, также возможно, что другие модули требуют их необязательно, что вынуждает JVM включать их в граф модулей.