Какой самый элегантный обходной путь для невозможности передать по ссылке в Java? - PullRequest
1 голос
/ 23 августа 2011

У меня есть глубоко вложенные структуры, и методы типа "remove(<Something>)", "contains(<Something>)" и т. Д. Полагаются на доступ к исходной ссылке, чтобы удалить ее и т. Д. (Копия ссылки не подходит).

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

Ответы [ 2 ]

3 голосов
/ 23 августа 2011

Методы типа remove и contains отлично работают с передачей по значению. Причина в том, что, хотя ссылки копируются, они имеют то же значение, что и оригинал. Просто посмотрите на API коллекций. Если вы делаете что-то вроде (psuedocode)

List list = new List();
list.add(object1) // assume you have an object1 reference

и тогда вы делаете

myRemove(list, object1);

и list, и object 1 передаются по значению, поэтому в методе myRemove они являются копиями исходной ссылки. Если в myRemove вы делаете

list.remove(object1);

объект по-прежнему удаляется из списка без проблем. Кроме того, поскольку ссылки list и object1 в обеих областях указывают на одни и те же базовые объекты, ссылка на список в вызывающей области ссылается на список, в котором объект удален.

Единственный раз, когда вам понадобится передать семантику ссылок, это если вы хотите изменить ссылку в методе и применить модификацию в области действия, вызвавшей метод.

Так что если вы хотите сделать

List myList = new List(); 
changeList(myList); 

и changeList меняют место, где myList указывает в области вызова, это не будет работать без хитрости. Обман называется двойная косвенность . По сути, вы создаете объект, который имеет экземпляр того, к чему вы хотите иметь доступ с помощью семантики передачи по ссылке, и вы передаете объект-контейнер вокруг.

So

class MyContainer {
    List list
}

теперь вы можете передать экземпляр MyContainer в метод и изменить значение списка, а также в области вызова, где точки list будут изменены. Обратите внимание, что здесь вы ничего особенного не делаете, все по-прежнему передается по значению.

0 голосов
/ 23 августа 2011

Как люди лучше всего справляются с этим, так что ...

Используя поля-члены (для работы со ссылками, а не копиями) и используя наследование и интерфейсы (для обработкивложенные структуры).

...