【问题标题】:Creating circular generic references创建循环通用引用
【发布时间】:2010-04-02 15:49:51
【问题描述】:

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

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

P2PClient<T extends P2PNetwork<? extends T>>

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

  1. 一个 P2PNetwork 由 特定类型的客户
  2. 一个 P2PClient 可能只属于一个 其客户端包括的网络 与此客户端相同的类型( 循环引用)

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

MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient;

和其他变体我从编译器收到大量错误。所以我的问题如下:

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

【问题讨论】:

  • 我仍然无法找到关于“是否可能”的明确答案,但是通过进一步阅读和尝试,我相信可以创建定义,但不能使用它来实例化对象。

标签: java generics circular-reference crtp


【解决方案1】:

循环泛型引用确实是可能的。 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);

【讨论】:

    【解决方案2】:

    如果您进一步定义“某种类型”的含义,即 P2PNetworks 的各种“类型”之间的区别是什么,这可能有助于我们回答您。

    但是与其用彼此的方式表达依赖/循环关系,不如通过引入第三个类P2PType来表达更容易:

    public class P2PNetwork<T extends P2PType> {
        ...
    }
    public class P2PClient<T extends P2PType> {
        ...
        public void setNetwork(P2PNetwork<T> network) { ... }
    }
    

    我可能忽略了一些东西,但我认为这将允许编译器强制 P2PClients 是相同泛型类型的 P2PNetworks 的一部分。

    但是,如果“类型”本身不适合表达为面向对象的东西,即如果P2PType 不是具有方法、多态行为等的东西,这种方法可能会失败。

    【讨论】:

    • 思想是类型是网络的目的。一个人为的例子:计算斐波纳契数与素数与确定生命意义的网络。前提是网络基类负责维护网络的状态和连通性,基客户端负责传播有关网络的信息并处理网络的实际任务。也就是说,这也成为了一个学术兴趣,即循环泛型定义是否可能,如果可能,它们将如何实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    • 2019-09-27
    • 1970-01-01
    • 2018-12-11
    • 2017-01-08
    • 1970-01-01
    相关资源
    最近更新 更多