В Java всегда используется механизм pass-by-value (передача по значению), но есть особенность для объектов:
Поэтому изменение полей объекта внутри метода отражается на оригинальном объекте, а вот попытка присвоить внутри метода новую ссылку переменной — никак не влияет на исходный объект. Это часто путают с pass-by-reference, но Java pass-by-reference не поддерживает!
Пример:
void changePrimitive(int a) { a = 10; } void changeObject(Point p) { p.x = 10; } int num = 5; changePrimitive(num); // num по-прежнему 5 Point pt = new Point(1, 2); changeObject(pt); // теперь pt.x == 10
Важно! Если внутри метода присвоить p = new Point(100, 200) — исходный объект вне метода не изменится. Меняется поле объекта, а не его ссылка!
Вопрос: Можно ли из метода поменять объект, переданный в аргументы, так, чтобы вне метода переменная-ссылка указывала на новый объект?
Ответ: Нет, нельзя. При присваивании новой ссылки аргументу внутри метода — это затрагивает только копию ссылки, которая пропадает после выхода из метода. Вне метода переменная-аргумент указывает на прежний объект.
void reassign(Point p) { p = new Point(100, 200); // только локально! } Point pt = new Point(5, 5); reassign(pt); // pt всё ещё (5, 5)
История
В крупной финансовой системе был реализован API, который "возвращал" изменения в объекте, модифицируя ссылку внутри метода. В результате после выхода из метода изменения не отражались. Понадобилось полностью перепроектировать часть логики, чтобы ясно разграничивать мутацию и возврат новых объектов.
История
При попытке реализовать swap для двух объектов в Java методом
swap(A a, B b)разработчик передавал ссылки и менял их местами внутри метода. Это не сработало. Необходимо либо возвращать результат, либо использовать контейнеры-массивы. Незнание pass-by-value привело к некорректному обмену объектов.
История
Один из участников проекта мигрировал логику с C++ и ожидал поведения pass-by-reference. В результате методы перестали работать должным образом: изменения внутри метода не "выходили" наружу. Понадобилось срочно переписать критичные участки кода, что заняло значительное время.