我正在阅读Esmond Pitt撰写的Java RMI书籍,我遇到了: -
“如果导出的对象是可序列化的,它仍然通过引用传递。导出对象的事实优先于它是可序列化的事实”
任何人都可以详细阐述原因。
答案 0 :(得分:0)
嗯,在某种程度上,我想他们必须选择其中一种。 (我不参加那次会议:)。
但是如果我有一个导出的远程对象,它需要序列化到它的存根(也就是说,它需要通过引用传递),否则,你将永远无法将它用作类似服务器的对象。 / p>
这有意义吗?如果你允许它被序列化,它也可能不是一个远程对象,因为你试图通过网络传递它时,你将无法发送存根(如果你想远程发送它就是你需要的)可访问),只需发送序列化副本。因此,它不再是一个远程对象了。
当然,您可能会问“为什么每次发生这种情况都不能动态选择”。那么,在这种情况下,你究竟如何管理这个过程而不会在软件的不相关部分之间造成一些可怕的耦合?
这是我的猜测:)
答案 1 :(得分:0)
导出必须优先于序列化目的而不是可序列化。否则RMI将无法运作。它只会成为一个移动代理协议。
例如, UnicastRemoteObject,
通过扩展Serializable
来实现RemoteObject
,这是可序列化的。如果你的远程对象像大多数一样扩展UnicastRemoteObject,
,它们会在构造时自动导出,并在序列化过程中自动替换为它们的存根,正如我在本书中引用的部分所描述的那样。
如果它没有这样做,优先于序列化本身,它就不会 UnicastRemoteObject,
它更像是一个移动代理,就像在本书的另一章中描述。
如果你想要它序列化,你必须先取消它。
我想我在书中也提到过,某些版本的Java会在到达时将它导出到接收器,因此它会成为一个回调。我无法理解这个功能。接收者总是可以自己出口,如果这是他想要的:我不明白为什么它被强加给他。
答案 2 :(得分:0)
http://docs.oracle.com/javase/tutorial/rmi/implementing.html
我希望此链接有用。
“控制参数和返回值如何传递的规则如下: 远程对象基本上是通过引用传递的。远程对象引用是存根,它是一个客户端代理,实现远程对象实现的完整远程接口集。 使用对象序列化通过副本传递本地对象。默认情况下,除了标记为静态或瞬态的字段外,将复制所有字段。可以在逐个类的基础上覆盖默认的序列化行为。“
说明: 这意味着,如果一个对象作为远程对象可供所有人使用,那么发送者将把引用放入流中并发送它(当发送者需要发送对象时)。接收器接收对原始对象的引用。 如果某个对象是可序列化的并且正在发送,则发件人会复制该对象并发送该副本,该副本在创建后是独立对象。