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

Методы: pass-by-value, перегрузка, varargs

Почему Java всегда pass-by-value, разрешение перегрузки на этапе компиляции и устройство varargs.

Java всегда pass-by-value

Java передаёт аргументы только по значению. Для примитива копируется его значение. Для объекта копируется ЗНАЧЕНИЕ ССЫЛКИ (адрес), а не сам объект — поэтому метод может менять состояние объекта через копию ссылки, но НЕ может переприсвоить ссылку вызывающего.

Отсюда развенчание мифа «объекты передаются по ссылке»: если внутри метода сделать param = new Something(), у вызывающего ничего не поменяется. Меняется состояние — да; меняется ссылка вызывающего — нет.

void rename(User u) { u.setName("X"); } // видно снаружи (меняем объект)
void reassign(User u) { u = new User(); } // НЕ видно снаружи (копия ссылки)

Перегрузка разрешается на компиляции

Перегрузка (overloading) — несколько методов с одним именем и разными списками параметров. В отличие от переопределения (overriding, выбор по фактическому типу в рантайме), перегрузка разрешается компилятором по СТАТИЧЕСКИМ типам аргументов.

Поэтому это разные механизмы: перегрузка — compile-time (статическая диспетчеризация), переопределение — runtime (динамическая). Путать их — частая ошибка.

Порядок выбора перегрузки

Компилятор ищет наиболее специфичный подходящий метод в три фазы: сначала без боксинга и varargs (точное совпадение и расширение примитивов, например int→long), затем с autoboxing/unboxing, и лишь в последнюю очередь — через varargs.

Эта приоритетность объясняет неожиданные выборы: например, при наличии перегрузок f(int) и f(Integer) вызов f(5) выберет примитивную версию (расширение раньше боксинга). Неоднозначность приводит к ошибке компиляции.

varargs

Параметр-varargs (Type... args) — это синтаксический сахар над массивом: внутри метода args является Type[], а на вызове компилятор сам собирает аргументы в массив (можно передать и готовый массив).

Тонкости: varargs участвует в разрешении перегрузки последним; передача null как varargs неоднозначна (null трактуется как сам массив); и каждый вызов создаёт массив — в горячем коде это лишние аллокации.

Как отвечать на собеседовании

Чётко скажите: Java — pass-by-value всегда, для объектов копируется значение ссылки (состояние менять можно, ссылку вызывающего — нет). Противопоставьте перегрузку (compile-time, по статическим типам) и переопределение (runtime), назовите три фазы выбора перегрузки (расширение → боксинг → varargs) и природу varargs как массива.

Вопросы по теме

Читайте также

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

Знать тему — половина дела

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

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