gpt4 book ai didi

java - 对于其他非模块化项目,如何使 Java 类在其模块之外不可见?

转载 作者:行者123 更新时间:2023-12-05 05:03:09 24 4
gpt4 key购买 nike

最近我发现,如果模块内的包包含公共(public)接口(interface)或类,它们会被自动导出,因此在接收者代码未模块化的情况下无意中在模块外部可见。

项目结构如下

parent

sub-donor (java-module)
my/project/first
Cowboy.java
module-info.java

sub-recipient (has no module-info)
my/project/somewhere
Main.java

module-info.java

module my.donor {
// nothing is exported here
}

牛仔.java

public class Cowboy {    
public String say() { return "eee-ha"; }
}

主.java

import my.project.first.Cowboy;

public class Main {
public static void main(String[] args) {
Cowboy g = new Cowboy();

System.out.println(g.say());
}
}

my.project.first 包中的类应该只在 my.donor 模块中使用,并且在模块外不可见。

出乎意料的是它在模块外是可见的,好像有 exports my.project.first; 行,所以类 Main 可以被编译。

限制可见性的方法是让sub-recipient成为一个java模块,添加module-info.java,然后是sub-donor<里面的所有东西 按预期隐藏。当然,对于任何其他非模块化项目,my.donor 模块中的每个公共(public)类都保持可见。

请查看最小 working example在 GitHub 上。

我很好奇这是bug还是有意识的设计。这种方法的目的是什么?

最佳答案

TL;DR — Maven 的问题。使用 javac 编译直接按预期工作。


冗长的版本

…Full command is just mvn compile on the parent project…

这就是你的问题。 Maven 有一个令人惊讶的特性,它只会将子项目视为 JPMS 模块IFF 所有子项目都有模块描述符。

因为只有您的 sub-donor Maven 模块具有 JPMS 模块描述符,所以您的两个子项目都在类路径上编译......

$ mvn -e -X compile

[INFO] Changes detected - recompiling the module!
[DEBUG] Classpath:
[DEBUG] sample-so-question-61888059-dev/sub-recipient/target/classes
[DEBUG] sample-so-question-61888059-dev/sub-donor/target/classes

[DEBUG] Command line options:
[DEBUG] -d sample-so-question-61888059-dev/sub-recipient/target/classes -classpath sample-so-question-61888059-dev/sub-recipient/target/classes;sample-so-question-61888059-dev/sub-donor/target/classes;…

并且因为两者都在类路径上,所以 sub-donor 子项目的模块描述符被渲染为无效。

如果您自己动手并直接运行 javac(假设您已经编译了 sub-donor预先项目)...

javac --add-modules my.donor --module-path sample-so-question-61888059-dev/sub-donor/target/classes --class-path sample-so-question-61888059-dev/sub-recipient/target/classes -d sample-so-question-61888059-dev/sub-recipient/target/classes sample-so-question-61888059-dev/sub-recipient/src/main/java/my/somewhere/*.java

然后 javac 确实像有意识地设计的那样退缩了……

sample-so-question-61888059-dev/sub-recipient/src/main/java/my/somewhere/Main.java:3: error: package my.project.first is not visible
import my.project.first.Cowboy;
^
(package my.project.first is declared in module my.donor, which does not export it)
1 error

关于java - 对于其他非模块化项目,如何使 Java 类在其模块之外不可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61888059/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com