在 Java 9 中,为什么在某些情况下对包冲突的处理方式有些不同?

In Java 9, why are package collisions treated a bit differently in some cases?

我正在试验 Java 9 并查看以下场景:

实验 1

运行 来自 'C' 的 main 给出运行时错误:

java.lang.RuntimeException: 包com.foo在模块B和模块A

实验二

与之前相同,但这次都导出 com.foo。

从 C 执行 main 的结果:

java.lang.module.ResolutionException:模块 B 和 A 导出包 com.foo 到模块 C

实验三

同2,但是这次我在模块C中声明了包com.foo

现在我得到一个编译错误: 错误:(4, 1) java:模块 C 从 A 和 B

中读取包 com.foo

为什么前两种情况在编译过程中也没有被捕获?是否有我不知道的运行时属性会在执行程序之前排除解析?

另外,关于报错信息:实验二的报错信息比实验一的报错信息好在哪里,不是说有一个模块不导出就结束了结果会有所不同。换句话说,产生不同的错误信息背后的考虑是什么?

实验 #2 和 #3 是拆分包问题,在编译时和 运行 时都应该是错误的。对于 #2,我无法从你的 post 中看出为什么你在编译 C 时看不到编译错误。你应该看到一个错误,其中包含 "module C reads package com.foo from both A and B".

这样的文本

实验 #1 可能是应用程序模块路径上的 A、B 和 C,由于包重叠,它们不能全部使用相同的名称 space(相同的 class 加载器)。您看到的错误消息在最近的版本中有所改进。

请注意,这里的实验已经在 jigsaw-dev 上的许多线程中进行了讨论,这可能是提出问题和经验的更好地方,至少在 JDK 9 仍在开发中。