我正在intelliJ中使用Java9:我创建了4个模块(所有模块都依赖于module1):
我认为自动模块应该要求所有公开的封装,而不是那些没有公开的。
我不明白封装的意义是什么,如果它只在显式模块化的JAR上工作。
我遗漏了什么?
发布于 2017-11-17 10:07:28
在您的示例中,module4将使而不是能够访问pkg2。自动模块读取所有其他模块(因为它们不能表示依赖关系),但是类型没有更改,因此只能访问导出包中的公共类型。
基于你的引语的一些背景:
我认为自动模块应该要求所有公开的封装,而不是那些没有公开的。
显式模块(即非自动模块)需要其他模块。在运行时,需要的指令是变成了。但是,它们并不是这些边的唯一来源:对于自动模块,每个解析模块都会添加一个边(即将其添加到可读性图中)。
所以,当你说“自动模块应该要求所有公开的包”时,会有一些错误,可能在翻译中丢失,但我还是想澄清一下。这句话应改为“自动模块读所有(已解决的)模块”。
在这个阶段,还没有人谈论可访问性和软件包。这是下一步,在这里,自动模块并不特殊,因此它们不能访问内部API。
发布于 2017-11-17 09:08:02
由于模块系统中的自动模块没有模块描述符(module-info.class),因此无法确定自动模块可能依赖的其他模块。
因此,在解析模块图之后,将生成一个自动模块,用于读取所有其他命名模块,无论是自动的还是显式的.。
因此,在您的示例中,module4是一个自动模块,可以读取显式模块module1。
模块系统中定义的可访问性(由我绘制)说明如下:如果在不同的模块中定义了S和T两种类型,而T是public,那么S中的代码可以访问T,条件是:
module4读取module1)和module1将pckg1导出到所有需要module1和pckg2的模块,仅将pckg2导出到module2)通过这种方式无法访问的跨模块边界引用的类型与私有方法或字段不可用的方式相同:任何使用它的尝试都会导致编译器报告错误,或者由Java虚拟机抛出
IllegalAccessError,或者由反射运行时API抛出IllegalAccessException。 因此,即使一个类型被声明为公共类型,如果它的包没有在其模块声明中导出,那么该模块中的代码也只能访问它。
发布于 2017-11-18 06:15:47
为了消除IntelliJ逻辑,我从我的模块(1、2和4)中构建了3个JAR,并开始在命令行中使用java来处理它们。
当我尝试仅使用-cp选项执行代码时,它具有相同的行为,即module4能够访问pkg2 ->,这使我得出这样的结论:如果IntelliJ模块中没有模块info.java文件,那么它使用类路径。
这里有一个棘手的部分:我使用了列表模块选项来确保module4的自动名称是module4。然后我执行了这样的命令:
java -p "<module1 path>;<module4 path>" -m module4/<MainClass>我已经从ClassNotFoundException (导出的包)获得了一个类的pkg1。
如果我执行:
java -p "<module1 path>;<module2 path>" -m module2/<MainClass>那么一切都正常。
因此,如果我们想要使用模块路径,主类必须来自一个模块化的JAR。
看起来,自动JAR是为了向后兼容,这样我们就可以将它们作为新模块的依赖项使用。
但是,如果希望使用模块路径执行模块,Java假设我们正在执行的JAR是一个模块化JAR,否则我们应该继续使用类路径。
换句话说,如果我们使用-p (modulepath)选项执行未调制的JAR,那么它将不需要路径中的其他模块。
所有这些结论都来自于玩弄Java,有人能告诉我它背后的确切理论部分吗?
https://stackoverflow.com/questions/47346736
复制相似问题