是的,支持可选依赖项。引用原始提案:
扩展模块声明的语言,以允许在指令上使用修饰符,具有以下含义:static
requires
因此,一个假设的模块声明形式
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将它们包含在模块图中。