为什么java RMI可以';无法通过引用获取返回值

为什么java RMI可以';无法通过引用获取返回值,java,rmi,pass-by-reference,rpc,Java,Rmi,Pass By Reference,Rpc,在RMI中,我只能通过 InetSocketAddress address = new InetSocketAddress(hostname, port); Server server = Stub.create(Server.class, address); int return = server.getValue(); 但是,我过不去 public class Return { int value; } InetSocketAddress address = new InetSoc

在RMI中,我只能通过

InetSocketAddress address = new InetSocketAddress(hostname, port);
Server server = Stub.create(Server.class, address);
int return = server.getValue();
但是,我过不去

public class Return {
    int value;
}
InetSocketAddress address = new InetSocketAddress(hostname, port);
Server server = Stub.create(Server.class, address);
Return return = new Return();
server.getValue(return);

我知道参数将被序列化和反序列化,但这不是我的问题,我的问题是“为什么Java不能像在使用RPC的C中那样,将传递引用模拟为传递输入输出?”,我认为这与Java环境有关。 我所说的in-out是指在带有RPC的C中,您可以通过

int return;
rpc.getValue(&return);

希望现在我的问题清楚了。

引用是计算机上的内存地址。使用RMI,您试图将该内存地址传递给(可能)另一台机器,而该内存地址在该上下文中没有意义。另一台机器现在不知道如何解释该地址。这就是可以传递值的唯一原因。

引用是计算机上的内存地址。使用RMI,您试图将该内存地址传递给(可能)另一台机器,而该内存地址在该上下文中没有意义。另一台机器现在不知道如何解释该地址。这就是可以传递值的唯一原因。

返回其他对象代理将带来实现挑战。目前,只有一种方法可以创建远程对象。如果只通过返回常规对象就允许方法生成更多的远程对象,那么所有这些调用都需要被拦截,对象需要被正确编目,等等


换句话说,Java人——不像e。GDCOM人员-决定不做额外的管道。这将永远是“为什么系统A不同于系统B”问题的答案。

返回额外的对象代理将带来实现挑战。目前,只有一种方法可以创建远程对象。如果只通过返回常规对象就允许方法生成更多的远程对象,那么所有这些调用都需要被拦截,对象需要被正确编目,等等


换句话说,Java人——不像e。GDCOM人员-决定不做额外的管道。这将永远是“为什么系统A不同于系统B”问题的答案。

当您通过“按引用传递”向方法传递参数时,您传递的是引用,这在远程调用中是不可能的。请记住,Java只支持传递值(甚至对象引用)

您可能会说RMI运行时可以将所有参数反序列化回客户端,但这就是问题所在:

假设您有一个Long as参数,那么java运行时将把它序列化到服务器,然后呢?它应该反序列化它吗?记住,long是不可变的


如果Java运行时创建了另一个Long实例,那么它如何更新引用旧Long(作为参数传递)的所有实例?

当您通过“按引用传递”将参数传递给方法时,您正在传递引用,这在远程调用中是不可能的。请记住,Java只支持传递值(甚至对象引用)

您可能会说RMI运行时可以将所有参数反序列化回客户端,但这就是问题所在:

假设您有一个Long as参数,那么java运行时将把它序列化到服务器,然后呢?它应该反序列化它吗?记住,long是不可变的


如果Java运行时创建了另一个Long实例,那么它如何更新引用旧Long(作为参数传递)的所有实例呢?

谢谢,但正如我所说的,在RPC中,它可以实现,调用函数后,据我所知,值将“写回”引用变量。我不同意。引用是引用对象的一种方式。它可以直接使用对象的内存地址(例如C++堆)实现,但也可能会被实现为路径<代码> /MexEx/ObjtSturt/SokXYXZ 或不透明整数对象ID。所有这些引用都可以传递给其他机器。谢谢,但是正如我所说,在RPC中,它可以实现,调用函数后,据我所知,值将“写回”引用变量。我不同意。引用是引用对象的一种方式。它可以直接使用对象的内存地址(例如C++堆)实现,但也可能会被实现为路径<代码> /MexEx/ObjtSturt/SoCKxYX或不透明的整数对象ID。所有这些引用都可以传递给其他机器。RMI不应该要求您作为单独的步骤专门获取返回值,您只需调用接口上的方法,这些方法将返回结果,就像在本地调用方法一样。很抱歉,我不太理解您的问题。@Andrzej Doyle我已经修改了代码,请再次检查,抱歉造成混淆。“我知道参数将被序列化和反序列化”。。。和返回值;在这两种情况下,除非相关对象是导出的远程对象。这是有文档记录的。您在哪个类上调用这些
getValue
方法?RMI不应该要求您作为单独的步骤专门获取返回值,您只需调用接口上的方法,这些方法将返回结果,就像在本地调用方法一样。很抱歉,我不太理解您的问题。@Andrzej Doyle我已经修改了代码,请再次检查,抱歉造成混淆。“我知道参数将被序列化和反序列化”。。。和返回值;在这两种情况下,除非相关对象是导出的远程对象。这是有案可查的。