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

MBZ*_*MBZ 9 java rmi

我已经阅读了有关使用RMI传递变量的各种文章.

他们中的一些人说,不可能通过RMI中的引用传递变量.例如:这一个这一个

虽然其他人说这是可能的.例如: 这一个,这一个这一个

任何人都可以清楚这一点吗?:)

hel*_*ios 5

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

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

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

  1. 复制完整的对象
  2. 发送一个远程引用(如果它是引用它必须是远程引用!).

样品

猜猜我们有服务.它是一个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();
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中你可以:

创建MyService的实现并发布它

Registry registry = LocateRegistry.createRegistry(port);
MyService stub = (MyService) UnicastRemoteObject.exportObject(server, 0);
registry.bind("myService", stub);`
Run Code Online (Sandbox Code Playgroud)

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

Registry registry = LocateRegistry.getRegistry(server, port);
MyService serv1 = (MyService) registry.lookup("myService");
Run Code Online (Sandbox Code Playgroud)

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

MyHandle handle1 = serv1.createX(...);
handle1.doOne()
Run Code Online (Sandbox Code Playgroud)

在此示例中,方法参数是序列化的(它应该是Serializable类),而返回的对象是对服务器中创建的对象的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
}
Run Code Online (Sandbox Code Playgroud)