通过引用传递,而不是在RMI中返回ArrayList

时间:2008-09-17 16:33:38

标签: java arraylist rmi

我的RMI调用定义为:

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

该函数执行数据库查找并填充两个ArrayLists。调用函数什么都没有。我相信这适用于矢量类型。

我是否需要使用Vector,或者有一种方法可以在不进行两次调用的情况下使其工作。我有一些其他的想法,我可能会使用,比如返回一个键/值对,但我想知道我是否可以让它工作。

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

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

进行远程通话时丢失了参考资料。您需要返回列表,而不是希望它们由远程调用填充。

答案 2 :(得分:1)

正如汤姆所提到的,你可以传递远程对象。您必须创建一个类来保存实现Remote的列表。无论何时传递实现Remote作为参数的东西,只要接收方使用它,它就会转向并向呼叫者远程调用返回以使用该对象。

答案 3 :(得分:1)

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

在这个具体的例子中,一个更好的方法是打破你的方法调用(因为你似乎在一个方法中做两件事:获取客户名称和获取客户号码),而是将你的结果返回给调用者而不是而不是传递一个集合...像这样:

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

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

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

这将导致通过线路进行两次单独的调用,但是更简洁,更简单的交互,并避免了原始示例中的参考中断问题。