Methods with Variable Number of Parameters

Introduction

Varargs (variable arguments) allow methods to accept any number of parameters.

Syntax:

returnType methodName(Type... parameterName)

Basic Example

public class Main {
    // Method with varargs
    static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }

    public static void main(String[] args) {
        System.out.println(sum());              // 0 (no arguments)
        System.out.println(sum(10));            // 10 (one argument)
        System.out.println(sum(10, 20));        // 30 (two arguments)
        System.out.println(sum(10, 20, 30));    // 60 (three arguments)
        System.out.println(sum(1, 2, 3, 4, 5)); // 15 (five arguments)
    }
}

Syntax Rules

  1. Three dots (…): Type...
  2. Only one varargs per method
  3. Must be last parameter
  4. Treated as array inside method
// ✓ Valid
void method1(int... nums) { }
void method2(String name, int... nums) { }
void method3(String s1, String s2, int... nums) { }

// ✗ Invalid
// void method4(int... nums, String name) { }  // Not last
// void method5(int... n1, int... n2) { }      // Multiple varargs

Varargs as Array

Inside method, varargs is an array.

public class Main {
    static void display(String... items) {
        System.out.println("Number of items: " + items.length);

        for (int i = 0; i < items.length; i++) {
            System.out.println("Item " + i + ": " + items[i]);
        }
    }

    public static void main(String[] args) {
        display("Apple", "Banana", "Orange");
    }
}

Output:

Number of items: 3
Item 0: Apple
Item 1: Banana
Item 2: Orange

Varargs with Other Parameters

public class Main {
    // Regular parameter + varargs
    static void greet(String greeting, String... names) {
        for (String name : names) {
            System.out.println(greeting + ", " + name + "!");
        }
    }

    public static void main(String[] args) {
        greet("Hello", "John");
        greet("Hi", "Alice", "Bob");
        greet("Welcome", "Tom", "Jerry", "Spike");
    }
}

Output:

Hello, John!
Hi, Alice!
Hi, Bob!
Welcome, Tom!
Welcome, Jerry!
Welcome, Spike!

Finding Maximum

public class Main {
    static int max(int... numbers) {
        if (numbers.length == 0) {
            throw new IllegalArgumentException("No arguments provided");
        }

        int maximum = numbers[0];
        for (int num : numbers) {
            if (num > maximum) {
                maximum = num;
            }
        }
        return maximum;
    }

    public static void main(String[] args) {
        System.out.println("Max of 5, 2, 8, 1: " + max(5, 2, 8, 1));
        System.out.println("Max of 10, 20: " + max(10, 20));
        System.out.println("Max of 100: " + max(100));
    }
}

String Concatenation

public class Main {
    static String concat(String separator, String... words) {
        if (words.length == 0) {
            return "";
        }

        StringBuilder result = new StringBuilder(words[0]);
        for (int i = 1; i < words.length; i++) {
            result.append(separator).append(words[i]);
        }
        return result.toString();
    }

    public static void main(String[] args) {
        System.out.println(concat(", ", "Apple", "Banana", "Orange"));
        System.out.println(concat(" - ", "Java", "Python", "C++"));
        System.out.println(concat(" | ", "Red", "Green", "Blue"));
    }
}

Output:

Apple, Banana, Orange
Java - Python - C++
Red | Green | Blue

Complete Example: Statistics

public class Main {
    static void statistics(int... numbers) {
        if (numbers.length == 0) {
            System.out.println("No numbers provided");
            return;
        }

        // Calculate statistics
        int sum = 0;
        int min = numbers[0];
        int max = numbers[0];

        for (int num : numbers) {
            sum += num;
            if (num < min) min = num;
            if (num > max) max = num;
        }

        double average = sum / (double) numbers.length;

        // Display results
        System.out.println("Count: " + numbers.length);
        System.out.println("Sum: " + sum);
        System.out.println("Average: " + average);
        System.out.println("Min: " + min);
        System.out.println("Max: " + max);
        System.out.println();
    }

    public static void main(String[] args) {
        statistics(10, 20, 30, 40, 50);
        statistics(5, 15, 25);
        statistics(100);
    }
}

Passing Array to Varargs

Can pass array directly to varargs method.

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

    public static void main(String[] args) {
        // Pass individual values
        System.out.println(sum(10, 20, 30));  // 60

        // Pass array
        int[] arr = {10, 20, 30, 40};
        System.out.println(sum(arr));  // 100
    }
}

Overloading with Varargs

public class Main {
    // Specific method
    static void print(String msg) {
        System.out.println("Single: " + msg);
    }

    // Varargs method
    static void print(String... messages) {
        System.out.println("Multiple: ");
        for (String msg : messages) {
            System.out.println("  " + msg);
        }
    }

    public static void main(String[] args) {
        print("Hello");              // Calls first method
        print("Hi", "Hello");        // Calls second method
        print("A", "B", "C");        // Calls second method
    }
}

Real-World Example: Logging

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

    static void info(String... messages) {
        log("INFO", messages);
    }

    static void error(String... messages) {
        log("ERROR", messages);
    }

    static void warning(String... messages) {
        log("WARNING", messages);
    }
}

public class Main {
    public static void main(String[] args) {
        Logger.info("Application started");
        Logger.info("User", "John", "logged in");
        Logger.warning("Low memory:", "Available", "10MB");
        Logger.error("Connection failed:", "Timeout", "after", "30s");
    }
}

Output:

[INFO] Application started
[INFO] User John logged in
[WARNING] Low memory: Available 10MB
[ERROR] Connection failed: Timeout after 30s

Varargs with Generics

public class Main {
    // Generic varargs
    static <T> void printAll(T... items) {
        for (T item : items) {
            System.out.println(item);
        }
    }

    public static void main(String[] args) {
        // String varargs
        printAll("Apple", "Banana", "Orange");

        System.out.println();

        // Integer varargs
        printAll(10, 20, 30, 40);

        System.out.println();

        // Mixed (Object)
        printAll("Hello", 123, true, 3.14);
    }
}

Empty Varargs

public class Main {
    static void process(String... items) {
        if (items.length == 0) {
            System.out.println("No items to process");
        } else {
            System.out.println("Processing " + items.length + " items");
        }
    }

    public static void main(String[] args) {
        process();                          // No items
        process("Item1");                   // 1 item
        process("Item1", "Item2");          // 2 items
    }
}

printf() Example

Java’s printf() uses varargs.

public class Main {
    public static void main(String[] args) {
        // printf signature: printf(String format, Object... args)

        System.out.printf("%d\n", 10);
        System.out.printf("%d + %d = %d\n", 10, 20, 30);
        System.out.printf("Name: %s, Age: %d, Score: %.2f\n",
                         "John", 25, 85.5);
    }
}

Calculator Example

public class Calculator {
    static double add(double... numbers) {
        double sum = 0;
        for (double num : numbers) {
            sum += num;
        }
        return sum;
    }

    static double multiply(double... numbers) {
        if (numbers.length == 0) return 0;

        double product = 1;
        for (double num : numbers) {
            product *= num;
        }
        return product;
    }

    static double average(double... numbers) {
        if (numbers.length == 0) return 0;
        return add(numbers) / numbers.length;
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("Sum: " + Calculator.add(10, 20, 30));
        System.out.println("Product: " + Calculator.multiply(2, 3, 4));
        System.out.println("Average: " + Calculator.average(10, 20, 30, 40));
    }
}

Varargs vs Array Parameter

Array Parameter:

static void method(int[] numbers) {
    // Must pass array
}

// Usage
int[] arr = {10, 20, 30};
method(arr);  // Must create array
// method(10, 20, 30);  // ✗ Error

Varargs:

static void method(int... numbers) {
    // Can pass individual values or array
}

// Usage
method(10, 20, 30);           // ✓ OK
int[] arr = {10, 20, 30};
method(arr);                  // ✓ OK

Performance Note

Varargs creates array internally.

// When you call:
sum(10, 20, 30);

// Java creates:
int[] temp = {10, 20, 30};
sum(temp);

For performance-critical code with fixed parameters, regular parameters may be better.


Multiple Method Signatures

public class Main {
    // Overload for common cases
    static int sum(int a, int b) {
        return a + b;
    }

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

    // Varargs for variable cases
    static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }

    public static void main(String[] args) {
        System.out.println(sum(10, 20));        // Calls first
        System.out.println(sum(10, 20, 30));    // Calls second
        System.out.println(sum(1, 2, 3, 4, 5)); // Calls third
    }
}

Common Use Cases

  1. Utility methods: Math operations
  2. String formatting: printf, format
  3. Logging: Multiple messages
  4. Collections: Arrays.asList()
  5. Testing: Assert methods

Quick Reference

// Declaration
returnType methodName(Type... paramName) {
    // paramName is an array
}

// Examples
void method1(int... nums) { }
void method2(String s, int... nums) { }
void method3(String s1, String s2, int... nums) { }

// Calling
method1();                    // 0 arguments
method1(10);                  // 1 argument
method1(10, 20, 30);          // 3 arguments

// Pass array
int[] arr = {10, 20, 30};
method1(arr);

// Inside method
void method(int... numbers) {
    int length = numbers.length;
    for (int num : numbers) {
        // Use num
    }
}

Common Mistakes

Mistake 1: Varargs Not Last

// ✗ Wrong
// void method(int... nums, String name) { }

// ✓ Correct
void method(String name, int... nums) { }

Mistake 2: Multiple Varargs

// ✗ Wrong
// void method(int... n1, String... n2) { }

// ✓ Use array or separate methods
void method(int[] n1, String... n2) { }

Mistake 3: Ambiguous Overloading

// ✗ Ambiguous
void method(int... nums) { }
void method(int n, int... nums) { }
// method(10) - which one?

Exam Tips

Remember:

  1. Varargs: variable number of arguments
  2. Syntax: Type... paramName
  3. Three dots (…) after type
  4. Only one varargs per method
  5. Must be last parameter
  6. Treated as array inside method
  7. Can pass 0 or more arguments
  8. Can pass array directly
  9. length gives number of arguments
  10. Creates array internally

Common Questions:

  • What are varargs?
  • Syntax for varargs?
  • Can we have multiple varargs?
  • Where must varargs be placed?
  • How to access varargs inside method?
  • Can we pass 0 arguments to varargs?
  • Difference between varargs and array parameter?
  • Can we pass array to varargs method?
  • How does varargs work internally?
  • Rules for varargs methods?