Что происходит с примитивным аргументом, переданным в метод, если внутри метода его изменить?
- Java передаёт аргументы по значению или по ссылке?
- Можно ли в Java написать метод swap для двух переменных?
- Может ли метод изменить переданный ему объект?
Ничего не произойдёт снаружи: Java всегда передаёт аргументы по значению, метод получает копию.
- Для ссылок копируется значение ссылки: состояние объекта менять можно, переприсвоение не видно снаружи
- Поэтому метод swap для переменных вызывающего написать нельзя
А ещё Правило одно для примитивов и ссылок — «по ссылке» в Java не бывает
Подробно
В 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 у параметра?
Разбор темы
- Методы: pass-by-value, перегрузка, varargs
Почему Java всегда pass-by-value, разрешение перегрузки на этапе компиляции и устройство varargs.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.