byStarTW says to YSITD
的类(如Spring注解标注的配置类),需要扫描特定包下的所有类。这通常会在程序启动的时候完成,这在相当程度上会减慢启动的过程。 模块将会提供一个API,允许调用者识别所有带有给定注解的类。一种预期的方式是为这样的类创建索引,这个索引会在模块编译的时候创建。 与已有的概念和工具集成 诊断工具(如栈跟踪信息)将会进行更新,其中会包含模块的信息。而且,它们还会集成到反射API中,这样就能按照操作类的方式来使用它们,还会包含版本信息,这一信息可以进行反射,也可以在运行时重载。 模块的设计能够让我们在使用构建工具时“尽可能地减少麻烦(with a minimum of fuss)”。编译之后的模块能够用在classpath中,也能作为一个模块来使用,这样的话,库的开发人员就没有必要为classpath应用和基于模块的应用分别创建多个构件了。 与其他模块系统的相互操作也进行了规划,这其中最著名的也就是OSGi。 尽管模块能够对其他的模块隐藏包,但是我们依然能够对模块包含的类和接口执行白盒测试。 特定OS的包 模块系统在设计时,始终考虑到了包管理器文件格式,“如RPM、Debian以及Solaris IPS”。开发人员不仅能够使用已有的工具将一组模块集合创建为特定OS的包,这些模块还能调用按照相同机制安装的其他模块。 开发人员还能够将组成应用的一组模块打包为特定OS的包,“终端用户能够按照目标系统的通用做法,安装和调用所打成的包”。基于上述的介绍,我们可以得知只有目标系统中不存在的模块才必须要打包进来。 动态配置 正在运行中的应用能够创建、运行并发布独立的模块配置。在这些配置中,可以包含开发者和平台模块。对于容器类架构,这会非常有用,如IDE、应用服务器或其他Java EE平台。 不兼容性 按照Java的惯例,这些变更在实现时,会强烈关注到向后的兼容性,所有标准和非废弃的API及机制都能够继续使用。但是项目可能会依赖其他缺乏文档的构造,这样的话,在往Java 9迁移的时候,就需要一些额外的工作了。 内部API不可用了 借助于强封装,每个模块能够明确声明哪些类型会作为其API的一部分。JDK将会使用这个特性来封装所有的内部API,因此它们会变得不可用了。 在Java 9所带来的不兼容性中,这可能是涵盖范围最大的一部分。但是这也是最明显的,因为它会导致编译错误。 那么,什么是内部API呢?毫无疑问,位于sun.*包中的所有内容。如果位于com.sun.*包中,或者使用了@jdk.Exported注解,在Oracle JDK中它依然是可用的,如果没有注解的话,那么它就是不可用的了。 能产生特殊问题的一个样例就是sun.misc.Unsafe类。它用在了很多项目中,用来实现关键任务或性能要求较高的代码,它将来可能不可用引发了很多的相关讨论。不过,在一次相关的交流中曾经提出,通过一个废弃的命令行标记,它依然是可用的。考虑到无法将其所有的功能都放到公开API中,这可能是一种必要的权衡。 另外一个样例是com.sun.javafx.*包中的所有内容。这些类对于构建JavaFX控件是至关重要的,并且它们还有一定数量的bug要修改。这些类中的大多数功能都会作为发布的目标。 合并JDK和JRE 在具有可扩展的Java运行时之后,它允许我们很灵活地创建运行时镜像,JDK和JRE就丧失了其独有的特性,它们只是模块组合中的两种形式而已。 这意味着,这两个构件将会具有相同的结构,包括目录结构也相同,任何依赖它(如在原来的JDK目录中会有名为jre的子目录)的代码就不能正常运行了。 内部JAR不可用了 像lib/rt.jar和lib/tools.jar这样的内部JAR将不可用了。它们的内容将会存储到特定实现的文件中,这些文件的格式还未明确说明,有可能会发生变化。 任何假设这些文件存在的代码将无法正确运行。这可能对IDE或其他严重依赖这些文件的工具带来一些切换的麻烦。