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