Java for Beginner
695 subscribers
603 photos
165 videos
12 files
937 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Самые пугающие три точки кода.

💬 Varargs в Java 💬

Сегодня в рабочем проекте столкнулся с методом, в аргументах которого было выражение типа Object... data.

Сразу подумал, что скорее всего на канале, этот момент не рассматривался. Нашел в коротком варианте, опубликованном аж 6 июня 2024 года.

Решил немного расширить взгляд на такой вариант передачи данных в метод.
Поддержка переменного числа аргументов (varargs) была добавлена в Java, начиная с версии JDK 5 (Java 5). До этого программисту приходилось либо перегружать методы для разного количества параметров, либо передавать массив аргументов вручную.

Иными словами - если у Вас возникает случай, что в метод может поступать неопределенное количество параметров, в том числе и разного типа, но метод должен быть только ОДИН - Varargs Ваш выбор 🤙


Как это работает? Теория. 🤓

Когда метод принимает аргументы через Varargs, то компилятор при этом неявно преобразует такой параметр в массив типа Object[].

void foo(Object... data) { /*...*/ }


по сути компилируется как
void foo(Object[] data) { /*...*/ }


При вызове метода с varargs компилятор сам создаёт массив нужного размера и заполняет его переданными значениями (даже если аргументов нет, создаётся пустой массив).

❗️При этом varargs-параметр может быть только последним в списке и быть единственным varargs в методе ❗️


Как это работает? Практика. 🧑‍💻

Пример метода, принимающего переменное число строк:
public static void printStrings(String... words) {
for (String w : words) {
System.out.print(w + " ");
}
System.out.println();
}

// Вызовы:
printStrings("Alice", "Bob");
printStrings("one", "two", "three");

При этом внутри words будет String[] со всеми переданными значениями


Или самый любимый вариант когда метод printAll(Object... args) может принимать любой набор объектов:
public static void printAll(Object... args) {
for (Object o : args) {
System.out.print(o + " ");
}
System.out.println();
}

// Вызов:
printAll("Hello", 123, true, new User("Tom"));


Здесь в args будут храниться объекты типа String, Integer, Boolean, User и т.д. Встроенный метод String.format тоже использует varargs: его сигнатура String.format(Locale, String, Object... args) позволяет передавать любое количество различных объектов в шаблон.


С каким 💩 можно столкнуться если увлекаться Varargs. ⛔️

Выборки из stackoverflow.com:
Приведение типов и автопакетирование

Метод void m(Object... args) под капотом видит args как Object[]. Если вы ожидаете внутри определённый тип, будьте осторожны с приведением, иначе может возникнуть ClassCastException. Попытка привести Object[] к String[] при неправильном использовании
varargs приведёт к ошибке времени выполнения.

Ещё один нюанс – работа с примитивными типами и их обёртками:
varargs не применяет автопакетирование к массивам примитивов. То есть если вы ожидаете набор чисел, стоит использовать Integer... вместо int..., иначе передача int[] в параметр типа Object... будет воспринята как единичный объект int[], а не как набор чисел.


Конфликт с перегрузкой методов

Перегрузка методов вместе с
varargs может привести к неоднозначности. Так, если объявлены оба метода fun(int... a) и fun(boolean... b), то вызов fun() без аргументов компилятор посчитает неразрешимым, ведь он не может однозначно выбрать, какую версию вызывать.

Аналогично, комбинация fun(int... a) и fun(int n, int... a) приводит к конфликту при вызове fun(1), потому что компилятор не знает, вызвать ли первый метод с одним элементом или второй метод с фиксированным первым параметром. Такие неоднозначности приводят к ошибкам компиляции. Чтобы этого избежать, не перегружайте методы только за счёт
varargs: лучше дать методам разные имена или явно менять количество параметров.


И личный совет: varargs удобны, но не злоупотребляйте ими. Старайтесь держать код ясным: ограничивайте использование varargs реальными случаями, где это упрощает интерфейс, и следите за типобезопасностью.


Понравился стиль подачи материала?

Отправь другу и ставь -
🔥

#Java #varargs #autor #для_новичков #junior
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6🤬11