Передача по ссылке не возвращается в RMI для ArrayList

StackOverflow https://stackoverflow.com/questions/85085

  •  01-07-2019
  •  | 
  •  

Вопрос

У меня есть вызов RMI, определенный как:

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

Функция выполняет поиск в базе данных и заполняет два списка ArrayList.Вызывающая функция ничего не получает.Я считаю, что это работает с векторными типами.

Нужно ли мне использовать Vector или есть способ заставить это работать без двух вызовов.У меня есть еще несколько идей, которые я бы, вероятно, использовал, например, возврат пары ключ/значение, но мне хотелось бы знать, смогу ли я заставить это работать.

Обновлять:
Я бы принял все ответы, данные до сих пор, если бы мог.Я не знал стоимость сети, поэтому имеет смысл переработать функцию, чтобы она возвращала LinkedHashMap вместо двух ArrayList.

Это было полезно?

Решение

Как упоминает Том, вы можете передавать удаленные объекты.Вам придется создать класс для хранения вашего списка, реализующего Remote.Каждый раз, когда вы передаете в качестве аргумента что-то, реализующее Remote, всякий раз, когда принимающая сторона использует это, она разворачивается и выполняет удаленный вызов. назад вызывающему объекту для работы с этим объектом.

Другие советы

Аргументы в RMI называются сериализованными.Десериализация на сервере создает копию списков.Если бы списки оставались на стороне клиента, то количество сетевых вызовов было бы достаточно большим.Вы можете передавать удаленные объекты, но будьте осторожны с последствиями для производительности.

Вы теряете свои рекомендации при удаленном звонке.Вам нужно будет вернуть списки, а не ожидать, что они будут заполнены удаленным вызовом.

Как уже упоминали другие, при передаче объектов в качестве параметров методу RMI объект будет сериализован, а затем десериализован на другом конце внутри целевого объекта, содержащего метод RMI.Это разрывает ссылку на переданные исходные объекты, поскольку теперь у вас есть два разных объекта:один в клиентском коде, вызывающем метод, и один на удаленной стороне.

В этом конкретном примере лучшим подходом было бы разбить вызовы методов (поскольку вы, похоже, делаете две вещи в одном методе:получение имен клиентов и получение номеров клиентов) и вместо этого ваши результаты возвращаются вызывающему абоненту, а не передаются в коллекцию... вот так:

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

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

Поскольку и ArrayList, и String реализуют Serializable, результаты в коллекции будут сериализованы и отправлены по сети в клиентский код, вызывающий метод, после чего вы сможете работать с данными так, как вам нужно.Если вместо этого вам нужно использовать пользовательский объект в коллекции, если ваш класс реализует интерфейс java.io.Serializable и соответствует спецификации этого интерфейса, у вас не должно возникнуть проблем.

Это приведет к двум отдельным вызовам по сети, но это гораздо более чистое и простое взаимодействие, а также позволяет избежать проблемы нарушения ссылок в исходном примере.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top