通过引用传递而不返回RMI中的ArrayList

时间:2020-03-05 18:59:19  来源:igfitidea点击:

我有一个RMI调用定义为:

public void remoteGetCustomerNameNumbers(ArrayList<String> customerNumberList, ArrayList<String> customerNameList) throws java.rmi.RemoteException;

该函数执行数据库查找并填充两个ArrayList。调用函数什么也没得到。我相信这适用于Vector类型。

我是否需要使用Vector,还是有一种方法可以在不打两个电话的情况下使它正常工作。我还有其他一些可能会用到的想法,例如返回键/值对,但是我想知道是否可以使它起作用。

更新:
如果可以的话,我将接受到目前为止给出的所有答案。我不知道网络成本,因此重新处理该函数以返回LinkedHashMap而不是返回两个ArrayLists是有意义的。

解决方案

回答

进行远程呼叫时,我们将丢失参考。我们需要返回列表,而不希望它们由远程调用填充。

回答

RMI中的参数称为序列化的。服务器上的反序列化将创建列表的副本。如果列表仍保留在客户端,则网络呼叫的数量将非常高。我们可以传递远程对象,但要注意性能影响。

回答

正如汤姆提到的,我们可以传递远程对象。我们必须创建一个类来保存实现Remote的列表。每当我们传递将Remote实现为参数的东西时,无论接收方何时使用它,它都会转过来并向调用方进行远程调用以使用该对象。

回答

正如其他人已经提到的那样,当将对象作为参数传递给RMI方法时,对象将被序列化,然后在包含RMI方法的目标对象内部的另一端反序列化。这打破了传入对象的引用,因为我们现在有了两个不同的对象:一个在调用此方法的客户端代码中,另一个在远程。

在此特定示例中,一种更好的方法是分解方法调用(因为我们似乎在一种方法中做了两件事:获取客户名称和获取客户编号),而是将结果返回给调用方,而不是传入像这样的一个集合:

public ArrayList<String> getCustomerNames() throws java.rmi.RemoteException;

public ArrayList<String> getCustomerNumbers() throws java.rmi.RemoteException;

由于ArrayList和String都实现了Serializable,因此集合中的结果将被序列化并通过电线发送到调用该方法的客户端代码,此时我们可以使用所需的数据。相反,如果我们需要在集合中使用自定义对象,则只要类实现了java.io.Serializable接口,并且遵循该接口的规范,我们就不会有问题。

这将导致通过电线进行两个单独的调用,但交互更简洁,更简单,并且避免了原始示例中的引用中断问题。