重要的提示: if 通过引用传递意味着修改方法内的参数值并更改调用者中的原始变量,你不能。如果你想做的是通过copy对对象的引用,以允许该方法与您的某个对象交互......是的,您可以。答案探讨了第二种选择。
是的。但它必须是一个 RMI 对象。在这种情况下,RMI 存根将通过副本传递。
RMI 通过两种方式传递参数和返回值:
- 复制完整对象
- send a remote参考(如果它是参考,它必须是远程的!)。
Sample
我猜我们有一项服务。它是一个 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 的实现并发布它
Registry registry = LocateRegistry.createRegistry(port);
MyService stub = (MyService) UnicastRemoteObject.exportObject(server, 0);
registry.bind("myService", stub);`
然后,一些 RMI 客户端可以获得对它的引用
Registry registry = LocateRegistry.getRegistry(server, port);
MyService serv1 = (MyService) registry.lookup("myService");
并且通过对服务对象的引用可以获得对其他RMI对象的引用。
MyHandle handle1 = serv1.createX(...);
handle1.doOne()
在此示例中,方法参数已序列化(它应该是可序列化类)
而返回的对象是对服务器中创建的对象的 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
}