实现接受(SocketImpl s)和对象复制

时间:2012-10-25 21:24:34

标签: java sockets copy

我正在根据 RAW套接字实现肯定确认和重传传输协议,在这种情况下,需要SocketImpl的子类。在实施accept方法时,我需要这样的东西:

protected void accept(SocketImpl s) {
    ...
    s.copy(socket);
}

其中socket是已计算的SocketImpl对象,必须将其复制到已初始化的 SocketImpl对象s。我需要一个将来源s.copy(socket)复制到目标socket可变复制方法 s。我知道存在Object clone()但它返回一个新的对象,我需要的是变异s

BTW你们有些人认为变异一个参数,在本例中是s,是破解设计。它不是Java标准库中的唯一示例。 implAccept(Socket s)类的ServerSocket是另一个例子。但这就是Sun / Oracle工程师设计它的方式。我想知道为什么这是一个如此糟糕的设计

乍一看,似乎有一定意义来提供通用的浅target.copy(source),其中target = souce.clone()等同于target = new TheClass(); target.copy(source);但由于它不存在(可能是有充分理由,请解释)唯一的方法是编写自定义逐字段复制方法

我是对的吗?感谢。

2 个答案:

答案 0 :(得分:1)

您误解了此方法的用途及其工作原理。我做过很多次了。提供给SocketImpl的{​​{1}}用于新接受的套接字,而不是implAccept()。所以你不需要第二个副本。您需要做的就是将ServerSocket包裹在SocketImpl或您自己派生的Socket类中。甚至还有一个Socket构造函数用于此目的,非常奇怪。

答案 1 :(得分:0)

我猜没有标准target.copy(source)(即可变复制方法),因为它比克隆更少需要:

  • 您需要单独决定(针对您的情况和所有领域),是否应该复制或相同(就像克隆与深度克隆一样);
  • 你通常可以设计一个只需切换外面的引用的设计,所以在你的情况下,你可以切换到使用引用s代替当前对象,这更简单,更多更高效。如果您需要复制值,则这对应于克隆(或使用复制构造函数);
  • 您可以通过在参数中包装参数(对象s)轻松实现它。

最后一点也回答你的第二个问题:或者逐字段复制,你可以实现一个转发类,将所有导出的SocketImpl方法转发到一个包装的核心SocketImpl:

  • 使用您当前的实现类C作为私有实现protected void accept(SocketImpl s)只是抛出异常;
  • 写一个转发类D
    • 包装一个SocketImpl(例如C的对象),保存在私有字段wrapped
    • 扩展SocketImpl并转发其所有方法,但accept转发到wrapped
    • 仅使用protected void accept(SocketImpl s)
    • 实现{ s.wrapped = this; }
  • 如果您希望在某些情况下复制所有字段,请为accept提供一个复制的参数,例如如果你想要在所有情况下复制,可以通过accept(s.clone())(或在accept内克隆);
  • 仅提供D类型的对象,以便永远不会抛出C中的异常。

¹accept的此实现仅适用于D类型的参数。否则,这个可怕的设计(必须改变作为参数给出的SocketImpl)需要accept使用丑陋的技术,例如反射(参见例如org.apache.harmony.luni.net.PlainSocketImpl http://www.docjar.com/html/api/org/apache/harmony/luni/net/PlainSocketImpl.java.html )。