在 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;
}
在 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;
}
没有。
有趣的是,模块系统状态和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
所以你甚至不能编译模块,更不用说在配置中使用它们了。
除了模块是自动模块,这个问题不会出现。只允许传递依赖,传递依赖绝不是循环的。