在Java 9中是否可以实现循环模块依赖关系?

在Java 9中,循环模块会被允许吗?如果不是,原因是什么?

module com.foo.bar {
    requires com.foo.baz;
    exports com.foo.bar.fizz;
}

module com.foo.baz {
    requires com.foo.bar;
    exports com.foo.baz.buzz;
}

答案 1

不。

文档

有趣的是,模块系统的状态Jigsaw快速入门指南都没有解决这个问题。一个来源(由Andy发现)是Alex Buckley的JavaOne演讲(请参阅他在这里解释)。最近的一个是开放问题列表,其中明确提到了循环依赖关系

当前草稿不允许在编译时、链接时和运行时解析模块图时循环。如果为自动模块添加可读性边缘或通过反射,则稍后会在运行时出现周期。[...]但是,这一约束不是成文的要求[...]。

理由

循环依赖性很糟糕,mkay。;)

当两个实体(方法,类,模块,项目等)协作但未充分解耦时,它们就会出现。对于用户和维护者来说,这种耦合意味着他们不能在不考虑另一个的情况下使用或改进一个。但这正是模块化试图实现的好处。

从上面链接的问题列表中:

在解析过程中不允许循环的理由是,它使模块图更容易推理,它简化了模块系统本身,并且从哲学上讲,循环中涉及的任何模块在逻辑上都是一个模块,因此首先应该将它们定义为一个模块。

实验

我在GitHub上创建了一个小演示项目,其中包含两个循环(:两个->一个->两个;三重:三>二>一>三)。尝试多模块编译,如快速入门指南中所示,以下是结果:

./compile.sh
 > creating clean directories
 > compiling and packaging cycle "pair"
src/org.codefx.demo.cyclic.pair.one/module-info.java:2: error: cyclic dependence involving org.codefx.demo.cyclic.pair.two
        requires org.codefx.demo.cyclic.pair.two;
                                            ^
1 error
 > compiling and packaging cycle "triple"
src/org.codefx.demo.cyclic.triple.three/module-info.java:2: error: cyclic dependence involving org.codefx.demo.cyclic.triple.two
        requires org.codefx.demo.cyclic.triple.two;
                                              ^
1 error

因此,您甚至无法编译模块,更不用说在配置中使用它们了。


答案 2

除了模块是自动模块外,不会出现问题。只允许传递依赖项,传递依赖项永远不会循环。


推荐