Получить доступ

Что происходит с примитивным аргументом, переданным в метод, если внутри метода его изменить?

JuniorОсновы языка
Ещё спрашивают так:
  • Java передаёт аргументы по значению или по ссылке?
  • Можно ли в Java написать метод swap для двух переменных?
  • Может ли метод изменить переданный ему объект?
Коротко

Ничего не произойдёт снаружи: Java всегда передаёт аргументы по значению, метод получает копию.

  • Для ссылок копируется значение ссылки: состояние объекта менять можно, переприсвоение не видно снаружи
  • Поэтому метод swap для переменных вызывающего написать нельзя

А ещё Правило одно для примитивов и ссылок — «по ссылке» в Java не бывает

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

В Java есть только передача по значению. Для примитива метод получает копию числа: x++ внутри метода меняет копию, переменная вызывающего остаётся прежней.

Для ссылочных типов копируется значение ссылки — адрес объекта. Поэтому:

  • через скопированную ссылку можно изменить состояние объекта (list.add(...)), и вызывающий это увидит — объект один;
  • переприсвоение параметра (list = new ArrayList<>()) меняет только локальную копию ссылки, снаружи ничего не происходит.

Отсюда классический вопрос: метод, меняющий местами две переменные вызывающего, в Java написать невозможно. Нужно вернуть результат (пару, массив, record) или менять содержимое общего объекта.

Путаница возникает из-за фразы «объекты передаются по ссылке» — точнее говорить, что ссылки передаются по значению.

Пример

static void inc(int x) { x++; }
static void addItem(List<String> list) { list.add("new"); }
static void replace(List<String> list) { list = new ArrayList<>(); }

int a = 1;          inc(a);          // a по-прежнему 1
List<String> l = new ArrayList<>();
addItem(l);                           // l содержит "new"
replace(l);                           // l не изменился

Что хотят услышать

  • Ответ: переменная вызывающего не меняется.
  • Java всегда передаёт по значению, для ссылок — значение ссылки.
  • Разница между изменением объекта и переприсвоением параметра.
  • Следствие про невозможность swap — плюс.

Частые ошибки

  • Говорить, что объекты передаются по ссылке.
  • Ожидать, что переприсваивание параметра изменит переменную вызывающего.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Ничего: метод работает с копией значения, переменная вызывающего не меняется
  • ✗Переменная вызывающего тоже изменится
  • ✗Изменение произойдёт только если параметр не объявлен final
  • ✗Будет ошибка компиляции

Что спросят дальше

  • Что будет, если внутри метода изменить поле переданного объекта?
  • Что меняет модификатор final у параметра?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем