Рекурсивный переход в объект по ссылке? ДЖАВА - PullRequest
2 голосов
/ 21 октября 2011

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

Ответы [ 2 ]

10 голосов
/ 21 октября 2011

Вы никогда передаете объект в качестве аргумента в Java. Вы либо передаете ссылку или примитивное значение. Аргумент всегда передается по значению. У Java вообще нет передачи по ссылке.

Если вы передаете ссылку на объект и хотите убедиться, что код, который вы вызываете, не изменяет данные в этом объекте, ваши варианты:

  • Создайте копию и передайте ссылку на нее
  • Сделайте ваш тип неизменным в первую очередь.

РЕДАКТИРОВАТЬ: Просто чтобы прояснить, если у вас есть:

Foo f = new Foo();

тогда значение f равно , а не a Foo объекта. Это ссылка на Foo объект. Если вы сейчас звоните:

doSomething(f);

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

В реальной аналогии: если я дам вам копию моего адреса, вы можете пойти и покрасить входную дверь, но вы не сможете изменить место, где я живу.

3 голосов
/ 21 октября 2011

Как утверждает Джон, все не примитивы передаются путем передачи копии ссылки.У тебя нет выбора.Таким образом, ваш рекурсивный метод должен иметь возможность обновлять объект, если он изменчив.ОДНАКО, вы не можете переназначить ссылку и ожидать, что она распространится обратно в стек вызовов.И помните, что строки не являются изменяемыми.

Другими словами, если вы выполните следующее, вы не изменили переданный объект:

void myMethod(Object o){
     o = new Object();
}

Приведенное выше изменение локальной ссылки наo, но не меняет ссылку вызывающего абонента на o.Если вам нужно сделать что-то подобное, вам нужно вернуть o.

...