В Java при передаче примитивных и объектных типов в функцию, передаются ли они по значению или по ссылке
Что проверяют
Знаете ли вы, что в Java передача всегда идёт по значению, и понимаете ли, что для объектов по значению передаётся ссылка. Следом обычно дают код: метод swap для двух объектов или присваивание нового объекта параметру, и просят сказать, что увидит вызывающий.
Как отвечать
Короткий ответ: передачи по ссылке в Java нет, только по значению. Разница в том, что именно копируется:
- примитивы (
int,long,booleanи остальные): копируется само значение. Изменения параметра внутри метода снаружи не видны; - объекты: переменная хранит ссылку, и в метод копируется эта ссылка. Копия и оригинал указывают на один объект, поэтому изменения его состояния (
list.add(x),user.setName(...)) видны снаружи; - присваивание параметру:
obj = new User()внутри метода меняет только локальную копию ссылки. Вызывающий код продолжает работать со старым объектом.
Лучшее доказательство это swap. Метод, который меняет местами два параметра, в Java ничего не меняет у вызывающего, в отличие от C++ со ссылками & или C# с ref.
Отдельно разберите неизменяемые типы. Про String и обёртки вроде Integer часто говорят, что они «передаются как примитивы». Это не так: ссылка копируется точно так же, просто у объекта нет методов, меняющих состояние. s += "x" внутри метода создаёт новую строку и переприсваивает локальную ссылку.
Практический вывод: если метод должен отдать новое значение, его возвращают через return или объект-результат, а не рассчитывают на изменение параметра. Мутацию переданных коллекций лучше делать явной или избегать, передавая неизменяемую копию через List.copyOf.
Где спотыкаются
Говорят «примитивы по значению, объекты по ссылке». Формулировка неверна, и интервьюер тут же проверит её на swap.
Смешивают две операции: изменение состояния объекта видно снаружи, а переприсваивание параметра нет.
Считают, что String ведёт себя иначе из-за особых правил передачи. Причина в неизменяемости, механизм передачи тот же.