我正在编写一个应用程序来在对等网络中进行一些分布式计算。在定义网络时,我有两类P2PNetwork和P2PClient。我希望这些是通用的,因此有以下定义:
P2PNetwork<T extends P2PClient<? extends P2PNetwork<T>>>
P2PClient<T extends P2PNetwork<? extends T>>
用P2PClient定义setNetwork(T网络)的方法。我希望用这段代码描述的是:
这对我来说似乎是正确的,但如果我尝试创建非通用版本,例如
MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient;
和其他变种我从编译器收到许多错误。所以我的问题如下:
答案 0 :(得分:25)
确实可以使用循环通用引用。 Java Generics and Collections包括几个例子。对于您的情况,这样的样本看起来像这样:
public interface P2PNetwork<N extends P2PNetwork<N, C>,
C extends P2PClient<N, C>> {
void addClient(C client);
}
public interface P2PClient<N extends P2PNetwork<N, C>,
C extends P2PClient<N, C>> {
void setNetwork(N network);
}
class TorrentNetwork implements P2PNetwork<TorrentNetwork, TorrentClient> {
@Override
public void addClient(TorrentClient client) {
...
}
}
class TorrentClient implements P2PClient<TorrentNetwork, TorrentClient> {
@Override
public void setNetwork(TorrentNetwork network) {
...
}
}
...
TorrentNetwork network = new TorrentNetwork();
TorrentClient client = new TorrentClient();
network.addClient(client);
答案 1 :(得分:3)
如果您进一步明确“某种类型”的含义,即P2P网络的各种“类型”之间存在差异,那么我们可以帮助您回答。
但是,不是通过相互表达依赖/循环关系,而是通过引入第三类P2PType
来表达更容易:
public class P2PNetwork<T extends P2PType> {
...
}
public class P2PClient<T extends P2PType> {
...
public void setNetwork(P2PNetwork<T> network) { ... }
}
我可能忽略了一些东西,但我认为这将允许编译器强制执行P2PClients是相同泛型类型的P2P网络的一部分。
然而,如果“类型”不适合表达为面向对象本身,即如果P2PType
不是具有方法,多态行为的东西,那么这种方法可能会分崩离析,等