不同包中的类使用封闭类

10
如果我声明了以下密封层次结构
package a;

import b.B;

public sealed interface A permits B {

}
package b;

import a.A;

public record B() implements A {

}

如果不使用模块(没有module-info.java),并且尝试使用Maven编译它,我会得到以下结果

[ERROR] .../src/main/java/a/A.java:[5,35] class a.A in unnamed module cannot extend a sealed class in a different package

我知道 https://openjdk.java.net/jeps/409 这个链接和其中的这部分内容:

被许可指定的类必须与超类位于相同的位置: 如果超类位于命名模块中,则必须在同一模块中;如果超类位于未命名模块中,则必须在同一包中。

然而,默认情况下,Maven 是否应该使用类路径进行编译呢?这个限制是否可以完全避免?

如果不能,这是否树立了一个先例,即模块路径上的功能比类路径更加灵活,并且反过来,虽然仍然支持类路径,但与模块路径相比不再是一等公民了?

1个回答

21

类路径即为未命名模块。

动机在于封闭类及其(直接)子类是紧密耦合的,因为它们必须一起编译和维护。在模块化的世界中,这意味着“同一模块”,而在非模块化的世界中,最好的近似是“同一包”。

所以,是的,如果您使用模块,会因为模块提供的安全边界获得一些额外的灵活性。


那么实质上,在Java 9之后,没有使用模块就无法编译某些东西了吗?这是我不确定的主要细节。 - Lovro Pandžić
5
不,那不正确。封闭类没有模块也可以正常工作;这意味着协同维护的边界是包。如果使用模块,您会获得更多的自由度,边界是该模块中的所有包。您可以将其视为积极的交互;您可以在没有模块的情况下使用封闭,或者在没有封闭的情况下使用模块,或者同时使用两者,如果同时使用它们,则可以获得某些额外的灵活性。 - Brian Goetz
3
另外,你不能在Java 9及以后的版本中真正地“没有模块”工作。您能做到的最接近的方法是将一堆东西塞进未命名模块(即类路径)。虽然这很接近,但并不完全等同于完全禁用模块。例如,JDK本身的类仍将位于模块中。 - Joachim Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接