创建循环通用引用

M. *_*sup 17 java generics crtp circular-reference

我正在编写一个应用程序来在对等网络中进行一些分布式计算.在定义网络时,我有两类P2PNetwork和P2PClient.我希望这些是通用的,因此有以下定义:

P2PNetwork<T extends P2PClient<? extends P2PNetwork<T>>>

P2PClient<T extends P2PNetwork<? extends T>>
Run Code Online (Sandbox Code Playgroud)

用P2PClient定义setNetwork(T网络)的方法.我希望用这段代码描述的是:

  1. P2P网络由特定类型的客户端构成
  2. P2PClient可能只属于其客户端与此客户端具有相同类型的网络(循环引用)

这似乎对我来说是正确的,但如果我尝试创建一个非泛型版本,如

MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient;
Run Code Online (Sandbox Code Playgroud)

和其他变种我从编译器收到很多错误.所以我的问题如下:

  1. 是否可以使用通用的循环引用(我从未见过明确禁止它的任何内容)?
  2. 上述通用定义是否是这种循环关系的正确定义?
  3. 如果它是有效的,它是描述这种关系的"正确"方式(即是否有另一个有效的定义,这在风格上是首选的)?
  4. 在给定正确的通用定义的情况下,如何正确定义客户端和服务器的非泛型实例?

Pét*_*rök 25

圆形通用引用确实是可能的.Java Generics和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);
Run Code Online (Sandbox Code Playgroud)