Java 在RMI中是否可以通过引用传递?

Java 在RMI中是否可以通过引用传递?,java,rmi,Java,Rmi,我读过关于使用RMI传递变量的各种文章 他们中的一些人说在RMI中不可能通过引用传递变量。e、 g:和 而其他人则认为这是可能的。例如。: ,及 有人能把这个弄清楚吗?:) 重要注意事项:如果通过引用传递意味着修改方法内的参数值并更改调用者中的原始变量,则不能。如果您想做的是将引用的副本传递给对象,以允许该方法与您的某个对象交互。。。是的,你可以。答案探讨了第二种选择 是的。但它必须是RMI对象。在这种情况下,RMI存根将通过副本传递 RMI以两种方式传递参数和返回值: 复制完整对象 发送远程引

我读过关于使用RMI传递变量的各种文章

他们中的一些人说在RMI中不可能通过引用传递变量。e、 g:和

而其他人则认为这是可能的。例如。: ,及


有人能把这个弄清楚吗?:)

重要注意事项:如果通过引用传递意味着修改方法内的参数值并更改调用者中的原始变量,则不能。如果您想做的是将引用的副本传递给对象,以允许该方法与您的某个对象交互。。。是的,你可以。答案探讨了第二种选择

是的。但它必须是RMI对象。在这种情况下,RMI存根将通过副本传递

RMI以两种方式传递参数和返回值:

  • 复制完整对象
  • 发送远程引用(如果是引用,则必须是远程的!)
  • 样本

    我想我们有服务。它是一个RMI对象,通过RMI注册表发布,因此客户端可以访问它。客户机可以对其调用一个方法(创建一些东西),服务希望返回对新创建的对象的引用。不是序列化副本,而是对服务器内存空间中创建的对象的引用

    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    // normally published object
    public interface MyService extends Remote
    {
        // creates something and return a "handle" to it
        public MyHandle createX(SomeSerializableObj param1) throws RemoteException;
    }
    
    // interface for object that the service will return a reference to...
    public interface MyHandle extends Remote
    {
        void doOne();
        void doTwo();
    }
    
    在本例中,您可以:

    创建MyService的实现并发布它

    然后,一些RMI客户机可以获得对它的引用

    并且通过对服务对象的引用可以获得对其他RMI对象的引用

    在本例中,方法参数是序列化的(它应该是一个可序列化的类) 而返回的对象是对服务器中创建的对象的RMI引用

    createX(…)的实现可以是:

    public MyHandle createX(...) {
       MyHandle handle = new MyHandleImpl(); // create an implementation
       createdHandlers.add(handle); // add it to some structure (just a sample)
       return handle; // return the implementation. RMI will send to client a RMI reference to this very instance
    }
    
    你的推荐信:

    (1) 表示RMI不支持按引用传递。我同意

    (2) 表示RMI不支持输入输出参数。我同意

    (3) 只是展示了按引用传递和按值传递引用之间通常存在的混淆。RMI做后者,就像Java的其他部分一样

    (4) 这是错误的

    (5) 这简直是语无伦次。RMI中没有传递引用

    RMI的远程“按值引用”与Java的本地“按值引用”在语义上基本相同,除了其他可能的故障模式


    您所读内容的含义是,对于非远程引用,RMI对象参数和结果是通过对象序列化按值传递的,而不是通过Java的按值传递引用的参数方法传递的。

    从最真实的意义上讲,不可以

    当您通过“引用”传递某个内容时,您真正做的是传递指向内存中某个位置的指针。当调用者和被调用者是同一个进程时,它们可以访问完全相同的堆。但将内存引用从计算机a传递到计算机B是毫无意义的,因为a无法访问Bs内存*

    然而,RMI允许您获取对远程对象的“引用”,但这并不完全相同,而且必须提前请求,将您的一个对象传递给服务器将产生一个副本

    直接从马嘴里(http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138781.html#3)

    RMI使用标准Java对象序列化机制传递对象。作为远程对象引用的参数作为远程引用传递。如果方法的参数是基元类型或本地(非远程)对象,则会将深度副本传递给服务器。返回值的处理方式相同,但方向相反。RMI允许您传递和返回本地对象的完整对象图以及对远程对象的引用

    可以通过引用传递远程对象,但不能将本地对象作为引用传递回服务器


    *从技术上讲,在一些大型分布式共享内存系统中,你可以,但我怀疑OP所说的是什么。

    谢谢:)但我不太明白你的答案:(你能举个例子吗?:)@MBZ在我看来,他已经给了你一个例子,但这只是通过值传递引用的另一个示例。它根本不是通过引用传递的。更改被调用方中引用的值不会更改调用方中引用的值。否决票。我明白你说的@EJP。这取决于MBZ的要求。如果她/他想向远程对象发送某种句柄,那么答案就是所需的。如果您想要过程语言中定义的“通过引用传递”,当然不是。我认为这是第一个选择。无论如何,我会补充一个澄清。重要提示:“通过引用传递”的意思是这样的。
    Registry registry = LocateRegistry.getRegistry(server, port);
    MyService serv1 = (MyService) registry.lookup("myService");
    
    MyHandle handle1 = serv1.createX(...);
    handle1.doOne()
    
    public MyHandle createX(...) {
       MyHandle handle = new MyHandleImpl(); // create an implementation
       createdHandlers.add(handle); // add it to some structure (just a sample)
       return handle; // return the implementation. RMI will send to client a RMI reference to this very instance
    }