是的,支持可选的依赖项。引用原始提案:
扩展模块声明的语言,以允许在指令
static上使用修饰符,其requires含义如下:
在编译时,
requires static M表示强制依赖。如果在可观察模块中找不到合适的模块并解决,这是一个错误。在编译时间之后的阶段中,
requires staticM表示可选的依赖性。分辨率期间,模块系统不会在可观察模块中搜索合适的模块,但是如果生成的模块图包含合适的模块,则它将在执行常规的分辨率后的健全性检查之前添加合适的可读性边缘。[…]因此,该形式的假设模块声明
module joda.beans { requires static joda.collect; ...}这样可以确保该
joda.collect模块在编译时可用,从而可以毫无问题地编译joda.beans引用的模块中的代码joda.collect。但是,它不能保证joda.collect在链接时或运行时可用。
(在此期间,为此功能创建了官方文档。)
我为此编写了一个演示。有趣的花絮是
module-info.java声明可选依赖项的模块的…
module org.prefx.demo.advent { // list the required modules requires org.prefx.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.prefx.demo.advent.factory.chocolate; requires static org.prefx.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.prefx.demo.advent.factory.chocolate,org.prefx.demo.advent.factory.quote -p mods -m org.prefx.demo.advent
当然,其他模块也可能非必需地要求它们,这迫使JVM将它们包括在模块图中。



