如何在Java模块中实现模块私有方法
我想创建一个Java IPC服务器模块(带有Jigsaw),它有两个包:如何在Java模块中实现模块私有方法,java,java-platform-module-system,Java,Java Platform Module System,我想创建一个Java IPC服务器模块(带有Jigsaw),它有两个包: com.example.ipc.backend com.example.ipc.backend.api 在mymodule info.java中,我有以下导出: module ipclib { exports com.example.ipc.backend.api; } 我可以在javafxgui模块中导入此模块,但在api模块中创建类时遇到问题 我在这个类中有一个接口,GUI模块中的某个类应该实现该接口,以
- com.example.ipc.backend
- com.example.ipc.backend.api
module info.java
中,我有以下导出:
module ipclib {
exports com.example.ipc.backend.api;
}
我可以在javafxgui模块中导入此模块,但在api
模块中创建类时遇到问题
我在这个类中有一个接口,GUI模块中的某个类应该实现该接口,以注册IPC模块中的更改(例如,当客户端连接到IPC服务器时):
然后,实现此接口的类应接收一个客户端
,其中包含有关所连接客户端的信息。这个Client
类在内部还保存了对线程的引用,该线程将套接字保存到客户端
public class Client {
private IpcConnection connection; //IpcConnection is from com.example.ipc.backend
public Client(IpcConnection connection) {
this.connection = connection;
}
}
现在我的问题是,每当创建新连接时,我都想在未导出的后端
模块中创建客户端
的实例。如何使构造函数仅在模块内可访问,而不公开
如果我将构造函数公开,IntelliJ会提供使用构造函数在GUI模块中创建新的客户端对象,但无权访问IpcConnection类。它提供了导出后端
模块的快速修复,但这不是我在导出api时想要的
因此,我想知道这是否仍然是“允许的”,因为Java编译器编译它时没有任何警告和问题,而这只是IntelliJ的问题。还是不应该这样做
但是,如果不允许这样做,我想知道为什么模块系统实际上只允许导出一些包,因为导出包和未导出包之间总是有一个边界(除非未导出类是从导出类内部调用的,而不是相反)
最小项目
模块“后端”
模块“gui”
我认为,这在java中是不可能的。不能声明“在命名空间A及其所有子命名空间中可见”的接口 与.net相比,Java并不真正了解“内部”原则。 如果在接口或类定义中省略了单词
public
,则该元素仅在其当前包中可见
但这不是递归的,因为它是在.net中(在.net中,您创建了一个只在当前项目中可见的internal
对象,无论是哪个子文件夹或名称空间)
在Java中,对象仅在其当前包中可见(即,同一名称空间)。子名称空间不包括在内。父命名空间也不是。如果我理解正确,您有子包
A
和B
,只有A
是公开的A
有一个类C
,该类的构造函数应该从B
调用,但不能公开
我认为最好的选择是让class
C
(Client
)实现一个公共接口。因此接口类可以在公共包中,而实际实现可以在非公共包中。您的问题有点难以理解。例如,在我认为您实际上是指“导出包”的地方,您一直使用术语“导出模块”。我也不完全确定您有哪些模块,哪些包在哪个模块中,或者每个类属于哪个包。你能不能请你的问题,让它更清楚你的确切设置是什么,以及你到底要完成什么?换句话说,a.谢谢,我添加了一个最小的示例。我对“我在这个类中有一个接口”有点困惑,我以为您有一个嵌套接口。您可以将客户端
设为接口,然后将实现保存在非导出包中。啊,当然可以。太明显了。谢谢
public class Client {
private IpcConnection connection; //IpcConnection is from com.example.ipc.backend
public Client(IpcConnection connection) {
this.connection = connection;
}
}
// backend/src/main/java/module-info.java
module ipclib {
exports com.example.ipc.backend.api;
}
// backend/src/main/java/com/example/ipc/backend/IpcConnection.java
package com.example.ipc.backend;
public class IpcConnection {
}
// backend/src/main/java/com/example/ipc/backend/api/Client.java
package com.example.ipc.backend.api;
import com.example.ipc.backend.IpcConnection;
public class Client {
private IpcConnection connection;
public Client(IpcConnection connection) {
this.connection = connection;
}
public String hello() {
return "Hello";
}
}
// backend/src/main/java/com/example/ipc/backend/api/IpcCallback.java
package com.example.ipc.backend.api;
public interface IpcCallback {
void clientConnected(Client client);
}
// gui/src/main/java/module-info.java
module gui {
requires ipclib;
}
// gui/src/main/java/com/example/ipc/gui/App.java
package com.example.ipc.gui;
import com.example.ipc.backend.api.Client;
import com.example.ipc.backend.api.IpcCallback;
public class App implements IpcCallback {
public static void main(String[] args) {
}
@Override
public void clientConnected(Client client) {
System.out.println(client.hello());
}
}