我正在根据 RAW套接字实现肯定确认和重传传输协议,在这种情况下,需要SocketImpl
的子类。在实施accept
方法时,我需要这样的东西:
protected void accept(SocketImpl s) {
...
s.copy(socket);
}
其中socket
是已计算的SocketImpl
对象,必须将其复制到已初始化的 SocketImpl
对象s
。我需要一个将来源s.copy(socket)
复制到目标socket
的可变复制方法 s
。我知道存在Object clone()
但它返回一个新的对象,我需要的是变异s
。
s
,是破解设计。它不是Java标准库中的唯一示例。 implAccept(Socket s)
类的ServerSocket
是另一个例子。但这就是Sun / Oracle工程师设计它的方式。我想知道为什么这是一个如此糟糕的设计
乍一看,似乎有一定意义来提供通用的浅target.copy(source)
,其中target = souce.clone()
等同于target = new TheClass(); target.copy(source)
;但由于它不存在(可能是有充分理由,请解释)唯一的方法是编写自定义逐字段复制方法。
我是对的吗?感谢。
答案 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
C
的对象),保存在私有字段wrapped
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 )。