【问题标题】:why java RMI can't get return value by reference为什么java RMI不能通过引用获取返回值
【发布时间】:2012-03-18 04:32:25
【问题描述】:

在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 不能像在 C 中使用 RPC 那样模拟传递引用作为传递传递? ",我认为它与java环境有关。 我所说的 in-out 我的意思是在带有 RPC 的 C 中,您可以通过

int return;
rpc.getValue(&return);

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

【问题讨论】:

  • 你在什么类上调用这些getValue 方法? RMI 不应该要求您作为单独的步骤专门获取返回值,您只需调用返回结果的接口上的方法,就像在本地调用方法一样。恐怕我不太了解你的问题。
  • @Andrzej Doyle 我已经修改了代码,请再次检查,很抱歉造成混乱。
  • "我知道参数会被序列化和反序列化" ... 返回值;在这两种情况下,除非相关对象是导出的远程对象。这是记录在案的。

标签: java rmi pass-by-reference rpc


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 谢谢,但正如我所说,在RPC中,它可以实现,在调用函数后,据我所知,值将“写回”到引用变量。
    • 我不同意。引用是引用对象的一种方式。它可以使用对象的内存地址(例如 C++ 堆)直接实现,但也可以实现为路径/machineX/objectstore/socketxyz 或不透明的整数对象 ID。所有这些引用都可以传递给其他机器。
    【解决方案3】:

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

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

    假设你有一个 Long 作为参数,那么 java 运行时会将它序列化到服务器,那么呢?它应该反序列化它吗?请记住,Long 是不可变的。

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

    【讨论】:

      猜你喜欢
      • 2017-02-10
      • 2014-07-04
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2020-04-01
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多