创建循环通用引用

时间:2010-04-02 15:49:52

标签: java generics circular-reference crtp

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

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

P2PClient<T extends P2PNetwork<? extends T>>

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

  1. P2P网络由 某种类型的客户
  2. P2PClient可能只属于a 客户端由网络组成的网络 与此客户相同的类型( 圆形参考)
  3. 这对我来说似乎是正确的,但如果我尝试创建非通用版本,例如

    MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient;
    

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

    1. 甚至是通用的循环引用 可能(我从未见过任何明确禁止它的东西)?
    2. 上面是通用定义a 正确定义这样一份通告 关系?
    3. 如果有效,是否“正确” 描述这种关系的方式 (即是否有另一个有效的 定义,风格上 优选的)?
    4. 我如何正确定义a 客户端的非通用实例 服务器给出了正确的通用 定义

2 个答案:

答案 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不是具有方法,多态行为的东西,那么这种方法可能会分崩离析,等