$ sudo teach IT
МОДУЛЬ 5 · УРОК 6

Vararg: переменное число аргументов

Методы, которые принимают любое количество параметров — от нуля до бесконечности

~20 минут Для новичков Java Массивы

Проблема: заранее неизвестное число аргументов

Допустим, вы хотите написать метод sum(), который складывает числа. Сколько чисел пользователь захочет сложить? Два? Пять? Сто? Вы не знаете заранее!

Первое, что приходит в голову — создать перегрузку метода для каждого возможного количества параметров:

int sum(int a, int b) {
    return a + b;
}

int sum(int a, int b, int c) {
    return a + b + c;
}

int sum(int a, int b, int c, int d) {
    return a + b + c + d;
}

int sum(int a, int b, int c, int d, int e) {
    return a + b + c + d + e;
}

Это работает, но это безумие! Представьте, что вам нужно поддерживать 50 вариантов — вам придётся написать 50 методов! И каждый раз, когда понадобится 51 параметр, придётся добавлять новый метод. Это не поддерживается и не масштабируется.

Можно передать массив:

int sum(int[] numbers) {
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

// Вызов:
int result = sum(new int[]{1, 2, 3, 4, 5});

Это лучше, но неудобно — вызывающий код выглядит громоздко с new int[]{...}. Есть ли способ сделать так, чтобы метод принимал просто список чисел без создания массива вручную?

Аналогия: Представьте, что вы заказываете пиццу по телефону. Оператор спрашивает: «Сколько у вас будет ингредиентов?» Вы: «Не знаю, зависит от моего аппетита». Оператор: «Тогда просто называйте их один за другим, я запишу все». Вот это и есть vararg — метод принимает столько аргументов, сколько вы ему передадите.

Решение этой проблемы — vararg (variable arguments, переменное число аргументов). Это специальный синтаксис Java, который позволяет методу принимать любое количество параметров одного типа.

Синтаксис vararg

Синтаксис vararg прост: после типа параметра ставится многоточие ...:

public static int sum(int... numbers) {
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

Вот и всё! Метод sum теперь принимает любое количество целых чисел. Многоточие ... — это ключевая часть синтаксиса. Оно говорит компилятору: «Этот параметр — это массив, но я хочу, чтобы вызывающий код мог передавать элементы по отдельности».

Пробел между типом и многоточием не обязателен — обе записи работают:

int sum(int... numbers)     // ✅ работает
int sum(int ... numbers)    // ✅ тоже работает
int sum(int ...numbers)     // ✅ и это тоже

Теперь можно вызывать метод тремя способами:

public static void main(String[] args) {
    // Способ 1: Передаём числа через запятую (без создания массива!)
    int result1 = sum(1, 2, 3);
    System.out.println(result1);  // 6

    // Способ 2: Передаём готовый массив
    int result2 = sum(new int[]{10, 20, 30, 40});
    System.out.println(result2);  // 100

    // Способ 3: Передаём ничего (пустой vararg)
    int result3 = sum();
    System.out.println(result3);  // 0
}

static int sum(int... numbers) {
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

Все три способа вызова работают одинаково. Java за кулисами преобразует переданные элементы в массив.

Запомните: Многоточие ... после типа — это не опечатка и не три точки. Это специальный синтаксис Java, который превращает параметр в массив, но позволяет вызывающему коду обращаться с ним как с отдельными аргументами.

Как Java работает с vararg внутри метода

Inside метода vararg параметр — это обычный массив. Вы можете использовать его точно так же, как любой другой массив:

static void process(String... messages) {
    System.out.println("Количество аргументов: " + messages.length);

    // Доступ по индексу
    for (int i = 0; i < messages.length; i++) {
        System.out.println("messages[" + i + "] = " + messages[i]);
    }

    // For-each
    for (String msg : messages) {
        System.out.println("Сообщение: " + msg);
    }

    // Проверка на пустоту
    if (messages.length == 0) {
        System.out.println("Нет сообщений");
    }

    // Первый и последний
    if (messages.length > 0) {
        System.out.println("Первое: " + messages[0]);
        System.out.println("Последнее: " + messages[messages.length - 1]);
    }
}

Внутри метода между vararg и обычным массивом нет никакой разницы. Вся магия происходит на стороне вызова — компилятор преобразует переданные аргументы в массив.

Пример: Метод для вывода чисел в столбик:

static void printNumbers(int... nums) {
    for (int i = 0; i < nums.length; i++) {
        System.out.println((i + 1) + ". " + nums[i]);
    }
    System.out.println("---");
}

public static void main(String[] args) {
    printNumbers(10, 20, 30);
    // Вывод:
    // 1. 10
    // 2. 20
    // 3. 30
    // ---

    printNumbers(5);
    // Вывод:
    // 1. 5
    // ---

    printNumbers();
    // Вывод: (пусто)
    // ---
}

Смешивание vararg с другими параметрами

Vararg можно комбинировать с обычными параметрами. Но есть важное правило: vararg всегда должен быть последним параметром.

Почему? Потому что компилятор не знает, где заканчиваются обычные параметры и начинается vararg. Если бы vararg был в середине, компилятор не смог бы определить, какой аргумент к какому параметру относится.

static void log(String level, String... messages) {
    System.out.println("[" + level + "]");
    for (String msg : messages) {
        System.out.println("  " + msg);
    }
}

public static void main(String[] args) {
    log("INFO", "Сервер запущен");
    log("ERROR", "Ошибка подключения", "Таймаут", "Код 504");
    log("DEBUG", "x=5", "y=10", "z=15");
}
// Вывод:
// [INFO]
//   Сервер запущен
// [ERROR]
//   Ошибка подключения
//   Таймаут
//   Код 504
// [DEBUG]
//   x=5
//   y=10
//   z=15

Правило: первые обязательные параметры идут первыми, vararg — последним:


static void example(int a, int b, String... rest)    // ✅ OK
static void example(String... rest, int a)            // ❌ Компиляция: vararg не последний!
static void example(int a, String... rest, int b)     // ❌ Компиляция: vararg не последний!

Пример: Метод для отправки email с несколькими получателями:

static void sendEmail(String from, String subject, String... to) {
    System.out.println("От: " + from);
    System.out.println("Тема: " + subject);
    System.out.print("Кому: ");
    for (int i = 0; i < to.length; i++) {
        if (i > 0) System.out.print(", ");
        System.out.print(to[i]);
    }
    System.out.println();
    System.out.println("---");
}

public static void main(String[] args) {
    sendEmail("admin@test.com", "Привет", "user1@test.com");
    sendEmail("boss@company.com", "Отчёт", "a@b.com", "c@d.com", "e@f.com");
}
// Вывод:
// От: admin@test.com
// Тема: Привет
// Кому: user1@test.com
// ---
// От: boss@company.com
// Тема: Отчёт
// Кому: a@b.com, c@d.com, e@f.com
// ---

Несколько обычных параметров + vararg

static void printTable(String header, char separator, int width, String... rows) {
    System.out.println("=".repeat(width));
    System.out.println(header);
    System.out.println("=".repeat(width));

    for (String row : rows) {
        System.out.println(separator + " " + row);
    }

    System.out.println("=".repeat(width));
}

Запомните: vararg ОБЯЗАН быть последним параметром в списке. Это строгое требование компилятора. Если вам нужно несколько vararg — их быть не может (об этом ниже).

Ограничения vararg

У vararg есть несколько важных ограничений, которые нужно знать:

Ограничение 1: Только один vararg в методе

Метод не может иметь два параметра vararg. Компилятор не сможет понять, какой аргумент к какому vararg относится.

// ❌ Ошибка компиляции:
static void wrong(int... a, int... b) {
}

// ❌ Ошибка компиляции:
static void wrong(String... names, int... numbers) {
}

Ограничение 2: Vararg должен быть последним

// ❌ Ошибка компиляции — vararg не последний:
static void wrong(int... nums, String name) {
}

// ✅ Правильно — vararg последний:
static void correct(String name, int... nums) {
}

Ограничение 3: Только для последнего параметра

Ключевое слово ... можно использовать только один раз, и только для последнего параметра:

// ✅ Один vararg — последний:
static void example(int a, int b, int... rest) {
}

// ❌ Нельзя два vararg:
static void example(int... a, int... b) {
}

// ❌ Нельзя vararg не последний:
static void example(int... a, int b) {
}

Ограничение 4: Vararg только для последнего параметра

Нельзя сделать vararg из примитивного типа, если после него идёт ещё параметр. Но сам по себе vararg с примитивными типами работает отлично:

static void sum(int... numbers)     // ✅ int vararg — ОК
static void avg(double... values)   // ✅ double vararg — ОК
static void print(String... texts)  // ✅ String vararg — ОК

Итого ограничения: (1) Один vararg на метод, (2) Vararg должен быть последним параметром, (3) После vararg нельзя добавить другие параметры.

Три способа вызова vararg метода

Мы уже видели это, но давайте закрепим — есть три способа вызвать метод с vararg:

static void show(String... items) {
    for (String item : items) {
        System.out.println("  - " + item);
    }
}

public static void main(String[] args) {
    System.out.println("Способ 1: Аргументы через запятую");
    show("яблоко", "банан", "вишня");

    System.out.println("\nСпособ 2: Готовый массив");
    String[] fruits = {"яблоко", "банан", "вишня"};
    show(fruits);

    System.out.println("\nСпособ 3: Ничего (пустой vararg)");
    show();
}
// Вывод:
// Способ 1: Аргументы через запятую
//   - яблоко
//   - банан
//   - вишня
//
// Способ 2: Готовый массив
//   - яблоко
//   - банан
//   - вишня
//
// Способ 3: Ничего (пустой vararg)

Все три способа эквивалентны — Java преобразует их в один и тот же массив внутри метода.

Vararg с разными типами

Object... — принимает что угодно

Если объявить vararg как Object..., метод будет принимать объекты любых типов:

static void printAll(Object... items) {
    for (Object item : items) {
        System.out.println(item.getClass().getSimpleName() + ": " + item);
    }
}

public static void main(String[] args) {
    printAll(42, "Привет", 3.14, true, 'A');
}
// Вывод:
// Integer: 42
// String: Привет
// Double: 3.14
// Boolean: true
// Character: A

String... — частый случай

static void log(String... messages) {
    for (String msg : messages) {
        System.out.println("[LOG] " + msg);
    }
}

log("Запуск программы", "Инициализация", "Готово");

double... — для вычислений

static double average(double... values) {
    if (values.length == 0) return 0;
    double sum = 0;
    for (double v : values) {
        sum += v;
    }
    return sum / values.length;
}

System.out.println(average(10.0, 20.0, 30.0));  // 20.0
System.out.println(average(5.5));                // 5.5
System.out.println(average());                   // 0.0

Перегрузка методов с vararg

Vararg можно комбинировать с перегрузкой методов, но здесь есть подводные камни. Когда есть несколько методов, которые могут подойти, компилятор выбирает наиболее специфичный.

static void show(int a) {
    System.out.println("int: " + a);
}

static void show(int a, int b) {
    System.out.println("int, int: " + a + ", " + b);
}

static void show(int... numbers) {
    System.out.println("vararg: ");
    for (int n : numbers) {
        System.out.println("  " + n);
    }
}

public static void main(String[] args) {
    show(1);          // int: 1 (вызывается show(int))
    show(1, 2);       // int, int: 1, 2 (вызывается show(int, int))
    show(1, 2, 3);    // vararg: 1, 2, 3 (вызывается show(int...))
    show();           // vararg: (вызывается show(int...) с пустым массивом)
}

Правила выбора метода:

  • Сначала ищется точное совпадение по количеству и типу параметров
  • Если не найдено — ищется метод с vararg подходящего типа
  • Vararg является наименее предпочтительным вариантом

Осторожно: Если перегрузка и vararg могут подойти одинаково хорошо, компилятор выдаст ошибку неоднозначности. Избегайте такой ситуации — лучше иметь один чёткий метод.

Внутреннее устройство: vararg — это сахар над массивами

Vararg — это не новая структура данных и не особый тип параметра. Это синтаксический сахар — удобная запись, которая компилятором преобразуется в обычный массив.

Когда вы пишете:

static int sum(int... numbers) {
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

Комилятор видит это как:

static int sum(int[] numbers) {
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

А когда вы вызываете sum(1, 2, 3), компилятор автоматически создаёт массив:

// Ваш вызов:
sum(1, 2, 3);

// Комилятор превращает в:
sum(new int[]{1, 2, 3});

Это означает, что внутри метода vararg ведёт себя абсолютно как обычный массив:

static void demonstrate(int... nums) {
    System.out.println("Тип: " + nums.getClass().getSimpleName());
    System.out.println("Длина: " + nums.length);
    System.out.println("Элемент 0: " + nums[0]);
    System.out.println("Это массив: " + (nums instanceof int[]));
}

demonstrate(10, 20, 30);
// Вывод:
// Тип: int[]
// Длина: 3
// Элемент 0: 10
// Это массив: true

Это важно понимать: vararg — это не «параметр переменной длины». Это именно массив. Просто записанный в удобном синтаксисе.

Vararg в реальном Java

Vararg активно используется в стандартной библиотеке Java. Вот самые известные примеры:

String.format()

String name = "Анна";
int age = 25;

String result = String.format("Меня зовут %s, мне %d лет", name, age);
System.out.println(result);
// Вывод: Меня зовут Анна, мне 25 лет

System.out.printf()

System.out.printf("Цена: %.2f руб., количество: %d%n", 99.9, 5);
// Вывод: Цена: 99.90 руб., количество: 5

Arrays.asList()

import java.util.Arrays;
import java.util.List;

List<String> list = Arrays.asList("А", "Б", "В", "Г");
System.out.println(list);
// Вывод: [А, Б, В, Г]

Collections.addAll()

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

List<Integer> nums = new ArrayList<>();
Collections.addAll(nums, 1, 2, 3, 4, 5);
System.out.println(nums);
// Вывод: [1, 2, 3, 4, 5]

EnumSet.of()

import java.util.EnumSet;

enum Color { RED, GREEN, BLUE, YELLOW }

EnumSet<Color> warmColors = EnumSet.of(Color.RED, Color.YELLOW);
System.out.println(warmColors);
// Вывод: [RED, YELLOW]

Logger и System.out.println

Метод println() вprintln() в Java не использует vararg, но многие логирующие библиотеки — например, SLF4J, Log4j — используют vararg для удобного форматирования сообщений:

Практические примеры

Задача 1: Метод sum — сумма любых чисел

static int sum(int... numbers) {
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

public static void main(String[] args) {
    System.out.println(sum(1, 2, 3));          // 6
    System.out.println(sum(10, 20, 30, 40));   // 100
    System.out.println(sum(5));                // 5
    System.out.println(sum());                 // 0
}

Задача 2: Метод max — найти максимум

static int max(int... numbers) {
    if (numbers.length == 0) {
        throw new IllegalArgumentException("Нужно хотя бы одно число!");
    }

    int max = numbers[0];
    for (int i = 1; i < numbers.length; i++) {
        if (numbers[i] > max) {
            max = numbers[i];
        }
    }
    return max;
}

public static void main(String[] args) {
    System.out.println(max(5, 3, 8, 1, 9));   // 9
    System.out.println(max(42));               // 42
    System.out.println(max(-5, -3, -8));       // -3
}

Задача 3: Метод min — найти минимум

static int min(int... numbers) {
    if (numbers.length == 0) {
        throw new IllegalArgumentException("Нужно хотя бы одно число!");
    }

    int min = numbers[0];
    for (int i = 1; i < numbers.length; i++) {
        if (numbers[i] < min) {
            min = numbers[i];
        }
    }
    return min;
}

public static void main(String[] args) {
    System.out.println(min(5, 3, 8, 1, 9));   // 1
    System.out.println(min(42));               // 42
}

Задача 4: Метод print — вывод с разделителем

static void print(String separator, String... messages) {
    for (int i = 0; i < messages.length; i++) {
        if (i > 0) {
            System.out.print(separator);
        }
        System.out.print(messages[i]);
    }
    System.out.println();
}

public static void main(String[] args) {
    print(", ", "Привет", "Мир", "Java");
    // Вывод: Привет, Мир, Java

    print(" | ", "Анна", "Борис", "Виктор", "Галина");
    // Вывод: Анна | Борис | Виктор | Галина
}

Задача 5: Метод join — объединение строк

static String join(String delimiter, String... words) {
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < words.length; i++) {
        if (i > 0) {
            result.append(delimiter);
        }
        result.append(words[i]);
    }
    return result.toString();
}

public static void main(String[] args) {
    String sentence = join(" ", "Java", "—", "отличный", "язык");
    System.out.println(sentence);
    // Вывод: Java — отличный язык

    String csv = join(",", "Иван", "25", "Программист");
    System.out.println(csv);
    // Вывод: Иван,25,Программист
}

Задача 6: Калькулятор с vararg

static double calculate(String operation, double... numbers) {
    if (numbers.length == 0) {
        throw new IllegalArgumentException("Нужны числа!");
    }

    double result = numbers[0];

    for (int i = 1; i < numbers.length; i++) {
        switch (operation) {
            case "+": result += numbers[i]; break;
            case "-": result -= numbers[i]; break;
            case "*": result *= numbers[i]; break;
            case "/": result /= numbers[i]; break;
        }
    }

    return result;
}

public static void main(String[] args) {
    System.out.println(calculate("+", 1, 2, 3, 4, 5));    // 15.0
    System.out.println(calculate("*", 2, 3, 4));           // 24.0
    System.out.println(calculate("-", 100, 25, 10, 5));    // 60.0
    System.out.println(calculate("/", 100, 2, 5));         // 10.0
}

Задача 7: Поиск элемента

static boolean contains(String target, String... items) {
    for (String item : items) {
        if (item.equals(target)) {
            return true;
        }
    }
    return false;
}

public static void main(String[] args) {
    System.out.println(contains("Java", "Python", "Java", "C++"));   // true
    System.out.println(contains("Ruby", "Python", "Java", "C++"));  // false
}

Задача 8: Валидатор (проверка обязательных полей)

static boolean allNonEmpty(String... fields) {
    for (String field : fields) {
        if (field == null || field.isEmpty()) {
            return false;
        }
    }
    return true;
}

public static void main(String[] args) {
    System.out.println(allNonEmpty("Иван", "ivan@mail.ru", "12345"));
    // true

    System.out.println(allNonEmpty("Иван", "", "12345"));
    // false
}

Типичные ошибки

Ошибка 1: Vararg не последний параметр

// ❌ Ошибка компиляции:
static void wrong(int... nums, String name) {
}

// ✅ Правильно:
static void correct(String name, int... nums) {
}

Ошибка 2: Два vararg параметра

// ❌ Ошибка компиляции:
static void wrong(int... a, int... b) {
}

// ✅ Решение — использовать один vararg:
static void correct(int... numbers) {
    // обработать все числа одним потоком
}

Ошибка 3: Неоднозначность при перегрузке

// ❌ Может вызвать неоднозначность:
static void show(int a) { }
static void show(int... nums) { }

show(1);  // Какой метод выбрать?

Ошибка 4: Путаница vararg с одиночным параметром

// Это РАЗНЫЕ сигнатуры:
static void process(int[] numbers) { }     // принимает массив
static void process(int... numbers) { }    // принимает vararg

// НО они не могут сосуществовать в одном классе — конфликт!

Ошибка 5: Забыть обработать пустой vararg

static int max(int... numbers) {
    // ❌ Если numbers пуст — ArrayIndexOutOfBoundsException!
    int max = numbers[0];
    for (int n : numbers) {
        if (n > max) max = n;
    }
    return max;
}

// ✅ Правильно:
static int max(int... numbers) {
    if (numbers.length == 0) {
        throw new IllegalArgumentException("Массив пуст!");
    }
    int max = numbers[0];
    for (int n : numbers) {
        if (n > max) max = n;
    }
    return max;
}

Более сложные примеры с vararg

Пример: метод для построения SQL-подобного запроса

Vararg удобен для методов, которые принимают список полей, значений или условий:

static String select(String table, String... columns) {
    StringBuilder query = new StringBuilder("SELECT ");
    for (int i = 0; i < columns.length; i++) {
        if (i > 0) query.append(", ");
        query.append(columns[i]);
    }
    query.append(" FROM ").append(table);
    return query.toString();
}

public static void main(String[] args) {
    System.out.println(select("users", "*"));
    System.out.println(select("users", "name", "email", "age"));
    System.out.println(select("orders", "id", "total", "date"));
}
// Вывод:
// SELECT * FROM users
// SELECT name, email, age FROM users
// SELECT id, total, date FROM orders

Пример: цепочка вызовов (builder-паттерн с vararg)

static String buildTag(String tag, String... attributes) {
    StringBuilder html = new StringBuilder("<" + tag);
    for (int i = 0; i < attributes.length; i += 2) {
        html.append(" ").append(attributes[i]).append("=\"").append(attributes[i + 1]).append("\"");
    }
    html.append(">");
    return html.toString();
}

public static void main(String[] args) {
    System.out.println(buildTag("a", "href", "https://java.com", "class", "link"));
    System.out.println(buildTag("input", "type", "text", "name", "email", "placeholder", "Введите email"));
}
// Вывод:
// <a href="https://java.com" class="link">
// <input type="text" name="email" placeholder="Введите email">

Пример: комбинирование vararg с泛型

static <T> java.util.List<T> listOf(T... items) {
    java.util.List<T> list = new java.util.ArrayList<>();
    for (T item : items) {
        list.add(item);
    }
    return list;
}

public static void main(String[] args) {
    java.util.List<Integer> numbers = listOf(1, 2, 3, 4, 5);
    java.util.List<String> names = listOf("Анна", "Борис", "Виктор");

    System.out.println(numbers);  // [1, 2, 3, 4, 5]
    System.out.println(names);    // [Анна, Борис, Виктор]
}

Пример: валидация email-адресов

static boolean isValidEmail(String email) {
    return email != null && email.contains("@") && email.contains(".") && email.length() > 5;
}

static boolean allEmailsValid(String... emails) {
    for (String email : emails) {
        if (!isValidEmail(email)) {
            System.out.println("Невалидный email: " + email);
            return false;
        }
    }
    return true;
}

public static void main(String[] args) {
    System.out.println(allEmailsValid("test@mail.com", "user@domain.org"));  // true
    System.out.println(allEmailsValid("test@mail.com", "invalid"));           // false
}

Сравнение vararg и ArrayList

Вы можете задаться вопросом: зачем использовать vararg, если есть ArrayList, который тоже может хранить произвольное количество элементов? Давайте сравним.

Критерий Vararg ArrayList
Синтаксис вызова sum(1, 2, 3) sum(list)
Изменяемость Нет (массив фиксирован) Да (add, remove)
Производительность Быстрее (массив) Чуть медленнее
Читаемость Отличная Хорошая
Когда использовать Метод принимает готовые данные Нужно динамически добавлять

Правило простое: если вы передаёте набор данных в метод и не планируете его изменять — используйте vararg. Если нужно динамически строить коллекцию — используйте ArrayList.

import java.util.ArrayList;
import java.util.List;

// Vararg — для передачи готовых данных
static int sumVararg(int... numbers) {
    int total = 0;
    for (int n : numbers) total += n;
    return total;
}

// ArrayList — для динамического построения
static List<Integer> buildList(int count) {
    List<Integer> list = new ArrayList<>();
    for (int i = 1; i <= count; i++) {
        list.add(i * 10);
    }
    return list;
}

public static void main(String[] args) {
    // Vararg: удобно передавать
    System.out.println(sumVararg(1, 2, 3, 4, 5));  // 15

    // ArrayList: динамическое построение
    List<Integer> numbers = buildList(5);
    System.out.println(numbers);  // [10, 20, 30, 40, 50]

    // Можно комбинировать!
    List<Integer> dynamic = buildList(3);
    System.out.println(sumVararg(dynamic.get(0), dynamic.get(1), dynamic.get(2)));
}

Итоговая сводка по модулю 5: Массивы

Вы прошли весь модуль по массивам! Вот краткое напоминание о каждом уроке:

  • Урок 1: Создание массивов, индексация, начальные значения, свойство length
  • Урок 2: Перебор массивов — for с индексом, for-each, копирование, Arrays.toString()
  • Урок 3: Методы Arrays — sort, binarySearch, fill, copyOf, equals, deepEquals
  • Урок 4: Многомерные массивы — таблицы, зубчатые массивы, матричные операции
  • Урок 5: Аргументы командной строки — String[] args, парсинг, валидация
  • Урок 6: Vararg — переменное число аргументов, синтаксис, ограничения

Массивы — фундамент программирования. Без них невозможно представить ни одну серьёзную программу. В следующих модулях мы узнаем, как хранить данные ещё удобнее — с помощью классов-обёрток и коллекций.

Итоги урока

  • Vararg (type... name) позволяет методу принимать любое количество параметров
  • Внутри метода vararg — это обычный массив, с которым работают все стандартные операции
  • Три способа вызова: аргументы через запятую, готовый массив, или ничего
  • Vararg ОБЯЗАН быть последним параметром в списке
  • В методе может быть только ОДИН vararg
  • Vararg — это синтаксический сахар над массивами, не новая структура данных
  • Широко используется в Java API: String.format(), Arrays.asList(), printf()
  • При перегрузке vararg является наименее предпочтительным вариантом
  • Vararg удобнее ArrayList для передачи готовых данных в метод
  • Это последний урок модуля — вы освоили все основы работы с массивами!

Это последний урок модуля 5 «Массивы»! Вы изучили создание массивов, перебор, методы Arrays, многомерные массивы, аргументы командной строки и vararg. Переходите к следующему модулю!

Тест: Vararg — переменное число аргументов

8 вопросов

Сумма через vararg

Premium