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

Java 实现接受(SocketImpl s)和对象复制,java,sockets,copy,Java,Sockets,Copy,我正在根据原始套接字实现一个肯定确认和重传传输协议,在这种情况下,需要SocketImpl的子类。在实现accept方法时,我需要如下内容: protected void accept(SocketImpl s) { ... s.copy(socket); } 其中,socket是一个已计算的SocketImpl对象,必须复制到一个已初始化的对象SocketImpl即我需要一个可变复制方法s.copy(socket)将源socket复制到目标s。我知道存在Object clon

我正在根据原始套接字实现一个肯定确认和重传传输协议,在这种情况下,需要
SocketImpl
的子类。在实现
accept
方法时,我需要如下内容:

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

顺便说一句,你们中的一些人认为,变异一个参数,在本例中是
s
,是一个破坏的设计。它不是Java标准库中的唯一示例<另一个例子是
ServerSocket
类的code>implacept(sockets)。但Sun/Oracle工程师就是这样设计的。我想知道为什么这是一个如此糟糕的设计

乍一看,提供一个通用的浅层
target.copy(source)
似乎有些道理,其中
target=souce.clone()
相当于
target=new TheClass();目标。复制(源)
;但是,由于它不存在(可能是出于合理的原因,请解释),唯一的方法是编程一个自定义字段一个字段的复制方法


我说得对吗?谢谢。

我想没有标准的
目标。复制(源)
(即可变复制方法)
,因为它比克隆需要少得多:

  • 您需要(针对您的情况和所有字段)分别决定它们是复制还是相同(就像克隆与深度克隆一样)
  • 您通常可以进行这样的设计,即您只需切换外部持有的引用,因此在您的情况下,您只需切换到使用引用
    s
    ,而不是到处使用当前对象,这更简单、更高效。如果需要复制的值,这对应于克隆(或使用复制构造函数)
  • 您可以通过包装参数(在您的例子中是object
    s
    )轻松实现它
最后一点也回答了您的第二个问题:除了逐字段复制之外,您还可以实现一个转发类,将SocketImpl的所有导出方法转发到包装的核心SocketImpl:

  • 使用当前的实现类
    C
    作为私有实现,使用
    受保护的void accept(SocketImpl s)
    只是抛出一个异常
  • 编写一个转发类
    D
    • 包装一个SocketImpl(例如
      C
      的对象),保存在私有字段
      wrapped
    • 扩展SocketImpl并将其所有方法转发到
      accept
      wrapped
    • 只需使用
      {s.wrapped=this;}
      ,即可实现受保护的void accept(SocketImpl s);⑨
  • 如果您希望在某些情况下复制所有字段,请为
    accept
    提供一个复制的参数,例如,通过
    accept(s.clone())
    (如果您希望在所有情况下复制,请在
    accept中进行克隆)
    
  • 只给出
    D
    类型的对象,这样
    C
    中的异常就不会被抛出


\
accept
的此实现仅适用于
D
类型的参数。否则,这种可怕的设计(必须改变作为参数给出的SocketImpl)需要
accept
使用丑陋的技术,例如反射(参见org.apache.harmony.luni.net.PlainSocketImpl at)。

您误解了这种方法的用途和工作原理。我已经做过很多次了。提供给
implacept()
SocketImpl
用于新接受的套接字,而不是
ServerSocket
。所以你不需要第二份。您只需将此
SocketImpl
包装到
Socket
或您自己的
Socket
派生类中即可。甚至有一个
Socket
构造函数就是为了这个目的而提供的,很奇怪。

你的最终意图是什么?扩展
SocketImpl
(或任何套接字,就这一点而言)是相当不寻常的事情。@Victor:虽然名称并不表示,但SocketImpl是抽象的。因此,扩展它应该是它最常用的用法之一;)@DaveBall是的,但在JDK1.6.33中扩展它的所有3个类都是JDK的内部类,其中2个类中有本机方法(这意味着它们本质上是JDK实现的一部分,不打算由应用程序程序员直接扩展)。在Java中,您不应该执行克隆或复制套接字。有一个操作系统内核可以做这些事情。@Victor:FYI我正在用原始IP套接字实现一个传输协议,所以SocketImpl子类是必需的也许我不明白,但是。。。我试图在原始套接字方面实现一个教育性的积极确认和重传协议,因此必须扩展
SocketImpl
。基本上
accept
--调用-->
implacpt
--调用-->
getImpl().accept(SocketImpl s)
。这是我要推翻的
s
是一个已经创建的对象,所以我除了对它进行变异外别无选择。如果我不高兴,请一如既往地开导我wrong@francesc除非使用JNI,否则您将无法以有意义的方式重写SocketImpl的
accept
。但如果您打算使用JNI,就没有必要扩展JDK类。似乎人们在java下使用“rocksaw”java库作为原始套接字,请参见@Victor:显然,我在使用JNI和一个比“rocksaw”简单得多的原始套接字接口进行教育purposes@francesc那么我为我这边的白噪音感到抱歉,不过,它是w