迁移到 Java 9 或更高版本时,是否需要切换到模块?

我们目前正在从 Java 8 迁移到 Java 11。但是,升级我们的服务并不像我们预期的那么痛苦。我们基本上只需要更改文件中的版本号,服务就可以愉快地启动并运行。我们升级了库以及使用这些库的(微)服务。直到现在还没有问题。build.gradle

是否需要实际切换到模块?恕我直言,这将产生不必要的成本。任何建议或进一步的阅读材料是值得赞赏的。

澄清一下,如果在不使用模块的情况下使用Java 9 +代码会有什么后果吗?例如,它会与其他代码不兼容吗?


答案 1

不。

无需切换到模块。

从不需要切换到模块。

Java 9 及更高版本通过未命名模块的概念支持传统类路径上的传统 JAR 文件,并且可能会在宇宙热寂之前这样做。

是否开始使用模块完全取决于您。

如果您维护一个没有太大变化的大型遗留项目,那么它可能不值得付出努力。

如果你从事一个多年来越来越难以维护的大型项目,那么模块化带来的清晰度和纪律可能是有益的,但它也可能是很多工作,所以在开始之前要仔细考虑。

如果你正在开始一个新项目,那么如果可以的话,我强烈建议你从模块开始。到目前为止,许多流行的库已经升级为模块,因此您所需的所有依赖项很有可能已经以模块化形式提供。

如果您维护一个库,那么我强烈建议您将其升级为模块,如果您尚未这样做,并且库的所有依赖项都已转换。

所有这一切并不是说在通过Java 8时你不会遇到一些绊脚石。但是,您遇到的那些可能与模块本身无关。自 2017 年发布 Java 9 以来,我们听到的最常见的迁移问题与版本字符串语法的更改以及内部 API(例如的删除或封装有关,这些 API 的公共、受支持的替代品已经存在多年。sun.misc.Base64Decoder


答案 2

我只能告诉你我的组织对此事的看法。我们正在为我们正在从事的每个项目迁移到模块。我们正在构建的基本上是微服务+一些客户端库。对于微服务来说,过渡到某种程度上是一个较低的优先级:那里的代码已经以某种方式隔离在docker容器中,所以“添加”模块在那里似乎并不重要(对我们来说)很重要。这项工作正在缓慢地进行,但它的优先级很低。modules

另一方面,客户端库是一个完全不同的故事。我不能告诉你我们有时遇到的混乱。我将解释一点我以前讨厌的。您向客户端公开一个接口,供所有人使用。自动地,那就是 - 暴露给世界。通常,我所做的是拥有一些不使用该接口的类,这些类不向客户端公开。我不希望客户使用它,它是内部的。听上去很好?错。jigsawinterfacepublicpackage-private

第一个问题是,当这些类增长,并且你想要更多的类时,保持所有内容隐藏的唯一方法是在同一包中创建类:package-private

  package abc:
        -- /* non-public */ Usage.java
        -- /* non-public */ HelperUsage.java
        -- /* non-public */ FactoryUsage.java
        ....

当它增长时(在我们的例子中确实如此),这些包太大了。搬到一个单独的包装,你说?当然,但那样会这样,我们从一开始就试图避免这种情况。HelperUsageFactoryUsagepublic

问题二:我们客户端的任何用户/调用者都可以创建相同的包名称并扩展这些隐藏类。它已经发生在我们身上几次了,有趣的时光。

modules以一种美丽的方式解决了这个问题:不再是真的了;我可以通过指令访问。这使得我们的代码生命周期和管理变得更加容易。我们远离了阶级道路地狱。当然,主要是为我们处理,但是当出现问题时,痛苦将非常真实。可能还有很多其他的例子。publicpublicfriendexports tomaven/gradle

也就是说,过渡(仍然)并不容易。首先,团队中的每个人都需要保持一致;其次是障碍。我仍然看到的最大的两个是:你如何根据什么来分离每个模块?我还没有一个明确的答案。第二个是,哦,美丽的“同一类由不同的模块导出”。如果您的库发生这种情况,有一些方法可以缓解;但如果这些是外部库...没那么容易。split-packages

如果您依赖 和(单独的模块),但它们都导出 ,您将大吃一惊。不过,有一些方法可以解决这个问题。不知何故痛苦,但可以解决。jarAjarBabc.def.Util

总的来说,自从我们迁移到模块(并且仍然这样做)以来,我们的代码变得更加干净。如果您的公司是“代码优先”公司,这很重要。另一方面,我参与过一些公司,如果这被高级建筑师视为“太贵”,“没有真正的好处”。


推荐