为什么我们需要在 java-9 模块系统中 requires static?

Why do we need requires static in java-9 module system?

我开始学习拼图 java-9 功能并阅读了一些 articles/video。

我无法理解可选依赖项的概念(requires static)

引自article

When a module needs to be compiled against types from another module but does not want to depend on it at run time, it can use a requires static clause. If foo requires static bar, the module system behaves different at compile and run time:

At compile time, bar must be present or there will be an error. During compilation bar is readable by foo.
At run time, bar might be absent and that will cause neither error nor warning. If it is present, it is readable by foo.

所以我想知道几件事:

  1. 为什么要让模块在编译时依赖于另一个模块而不是在运行时?有什么例子吗?龙目岛之类的乐器?

  2. 在 java 之前 java-9 ?

  3. 中可选依赖项的任何类似物

P.S.

我又找到了一种解释: 引自 article:

Sometimes we write code that references another module, but that users of our library will never want to use.

For instance, we might write a utility function that pretty-prints our internal state when another logging module is present. But, not every consumer of our library will want this functionality, and they don’t want to include an extra logging library.

In these cases, we want to use an optional dependency. By using the requires static directive, we create a compile-time-only dependency:

module my.module {
    requires static module.name;
}

但我完全不清楚。谁能用简单的方式解释一下?

  1. 有相当数量的库,只有在编译时才有意义。大多数情况下,这涉及仅在开发过程中提供帮助的注释(例如防止错误、减少样板文件)。一些示例包括:


    这些注释往往有 SOURCECLASSRetentionPolicy,这意味着它们在运行时没有用(甚至不可用)。为什么在部署时将这些依赖项与应用程序的其余部分一起提供?如果没有 requires static,您将 被迫 在部署时包含它们,否则您的应用程序将由于缺少依赖项而无法启动。

  2. 您也可以将这些依赖项声明为可选 pre-Java 9。许多重要的 Java 项目都使用 Maven 或 Gradle 等构建工具。除了那些自动构建和测试您的项目的工具之外,它们所做的很大一部分工作是 依赖管理 。我对 Maven 不够熟悉,但是在使用 Gradle 时会使用:

    dependencies {
        compileOnly 'group.id:artifact-id:version'
    }
    

    声明运行时不需要的依赖项。

如果Dependent Module 在编译时可用但在rumtime 时可选,那么这种类型的依赖称为可选依赖。我们可以使用 static 关键字指定可选依赖。

注意 static关键字用来表示"This dependency check is mandatory at compile time and optional at runtime."

例1

module moduleB {
  requires moduleA;
}

moudleA 应该在编译和 rumtime 时可用。它不是可选依赖。

例2.

module moduleB {
   requires static moduleA;
}

在编译时模块 A 应该可用,但在运行时它是可选的,即在运行时甚至模块 A 不可用 JVM 将执行代码。