Methods & Scope
Varargs
Variable Arguments
You're building a logging method. Sometimes you log one value, sometimes five. Instead of overloading for every count, varargs lets you accept any number of arguments with a single method definition.
Accept any number of arguments
Define a method that takes zero or more values.
public class BasicVarargs {
public static void main(String[] args) {
System.out.println("=== Basic Varargs ===\n");
// Call with different numbers of arguments
printAll(); // Zero args
printAll("Hello"); // One arg
printAll("Alice", "Bob"); // Two args
printAll("Red", "Green", "Blue"); // Three args
System.out.println("\n=== Inside the Method ===");
showDetails("a", "b", "c");
// Typed varargs
System.out.println("\n=== Integer Varargs ===");
showNumbers(10, 20, 30, 40);
}
// Varargs method
static void printAll(String... messages) {
System.out.println("Called with " + messages.length + " argument(s):");
for (String msg : messages) {
System.out.println(" - " + msg);
}
}
static void showDetails(String... items) {
System.out.println("items.getClass(): " + items.getClass().getSimpleName());
System.out.println("items.length: " + items.length);
System.out.print("items contents: ");
for (int i = 0; i < items.length; i++) {
System.out.print(items[i]);
if (i < items.length - 1) System.out.print(", ");
}
System.out.println();
}
// Integer varargs
static void showNumbers(int... nums) {
System.out.println("Received " + nums.length + " integers");
int sum = 0;
for (int n : nums) sum += n;
System.out.println("Sum: " + sum);
}
}
Use Type... name syntax. Inside the method, it's an array.
Sum any count of numbers
Calculate the sum of however many numbers are passed.
public class SumNumbers {
public static void main(String[] args) {
System.out.println("=== Summing with Varargs ===\n");
// Sum different counts of numbers
int bonus = ;
System.out.println("sum() = " + sum());
System.out.println("sum(" + bonus + ") = " + sum(bonus));
System.out.println("sum(1, 2, " + bonus + ") = " + sum(1, 2, bonus));
System.out.println("sum(10, 20, 30, 40, " + bonus + ") = " + sum(10, 20, 30, 40, bonus));
System.out.println("\n=== Finding Max ===");
System.out.println("max(5) = " + max(5));
System.out.println("max(3, 7, 2) = " + max(3, 7, 2));
System.out.println("max(10, -5, 8, 20, 15) = " + max(10, -5, 8, 20, 15));
// Extended stats
System.out.println("\n=== Statistics ===");
stats(1, 2, 3, 4, bonus);
stats(10, 20, 30);
}
static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
static int max(int first, int... rest) {
// first guarantees at least one argument
int maximum = first;
for (int n : rest) {
if (n > maximum) {
maximum = n;
}
}
return maximum;
}
// Stats helper
static void stats(int... numbers) {
if (numbers.length == 0) {
System.out.println("No numbers provided");
return;
}
int sum = 0, min = numbers[0], max = numbers[0];
for (int n : numbers) {
sum += n;
if (n < min) min = n;
if (n > max) max = n;
}
double avg = (double) sum / numbers.length;
System.out.printf("Count: %d, Sum: %d, Avg: %.2f, Min: %d, Max: %d%n",
numbers.length, sum, avg, min, max);
}
}
public class SumNumbers {
public static void main(String[] args) {
System.out.println("=== Summing with Varargs ===\n");
// Sum different counts of numbers
int bonus = ;
System.out.println("sum() = " + sum());
System.out.println("sum(" + bonus + ") = " + sum(bonus));
System.out.println("sum(1, 2, " + bonus + ") = " + sum(1, 2, bonus));
System.out.println("sum(10, 20, 30, 40, " + bonus + ") = " + sum(10, 20, 30, 40, bonus));
System.out.println("\n=== Finding Max ===");
System.out.println("max(5) = " + max(5));
System.out.println("max(3, 7, 2) = " + max(3, 7, 2));
System.out.println("max(10, -5, 8, 20, 15) = " + max(10, -5, 8, 20, 15));
// Extended stats
System.out.println("\n=== Statistics ===");
stats(1, 2, 3, 4, bonus);
stats(10, 20, 30);
}
static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
static int max(int first, int... rest) {
// first guarantees at least one argument
int maximum = first;
for (int n : rest) {
if (n > maximum) {
maximum = n;
}
}
return maximum;
}
// Stats helper
static void stats(int... numbers) {
if (numbers.length == 0) {
System.out.println("No numbers provided");
return;
}
int sum = 0, min = numbers[0], max = numbers[0];
for (int n : numbers) {
sum += n;
if (n < min) min = n;
if (n > max) max = n;
}
double avg = (double) sum / numbers.length;
System.out.printf("Count: %d, Sum: %d, Avg: %.2f, Min: %d, Max: %d%n",
numbers.length, sum, avg, min, max);
}
}
public class SumNumbers {
public static void main(String[] args) {
System.out.println("=== Summing with Varargs ===\n");
// Sum different counts of numbers
int bonus = ;
System.out.println("sum() = " + sum());
System.out.println("sum(" + bonus + ") = " + sum(bonus));
System.out.println("sum(1, 2, " + bonus + ") = " + sum(1, 2, bonus));
System.out.println("sum(10, 20, 30, 40, " + bonus + ") = " + sum(10, 20, 30, 40, bonus));
System.out.println("\n=== Finding Max ===");
System.out.println("max(5) = " + max(5));
System.out.println("max(3, 7, 2) = " + max(3, 7, 2));
System.out.println("max(10, -5, 8, 20, 15) = " + max(10, -5, 8, 20, 15));
// Extended stats
System.out.println("\n=== Statistics ===");
stats(1, 2, 3, 4, bonus);
stats(10, 20, 30);
}
static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
static int max(int first, int... rest) {
// first guarantees at least one argument
int maximum = first;
for (int n : rest) {
if (n > maximum) {
maximum = n;
}
}
return maximum;
}
// Stats helper
static void stats(int... numbers) {
if (numbers.length == 0) {
System.out.println("No numbers provided");
return;
}
int sum = 0, min = numbers[0], max = numbers[0];
for (int n : numbers) {
sum += n;
if (n < min) min = n;
if (n > max) max = n;
}
double avg = (double) sum / numbers.length;
System.out.printf("Count: %d, Sum: %d, Avg: %.2f, Min: %d, Max: %d%n",
numbers.length, sum, avg, min, max);
}
}
Loop through the varargs array just like any array.
Combine regular and varargs parameters
Mix required parameters with varargs.
public class MixedParams {
public static void main(String[] args) {
System.out.println("=== Mixed Parameters with Varargs ===\n");
// Required params + varargs
log("INFO", "System started");
log("DEBUG", "Loading config", "user.properties");
log("ERROR", "Failed to connect", "timeout", "retry=3");
System.out.println("\n=== Shopping Cart ===");
printReceipt("Alice", 10.99, 24.50, 5.25);
printReceipt("Bob", 99.99);
System.out.println("\n=== Team Roster ===");
printTeam("Engineering", "Alice", "Bob", "Charlie");
printTeam("Marketing", "Diana", "Eve");
printTeam("Executive"); // No members
}
// Level (required) + message (required) + details (varargs)
static void log(String level, String message, String... details) {
System.out.print("[" + level + "] " + message);
if (details.length > 0) {
System.out.print(" | ");
System.out.print(String.join(", ", details));
}
System.out.println();
}
// Name + prices (at least one price makes sense)
static void printReceipt(String customer, double... prices) {
System.out.println("Receipt for: " + customer);
double total = 0;
for (int i = 0; i < prices.length; i++) {
System.out.printf(" Item %d: $%.2f%n", i + 1, prices[i]);
total += prices[i];
}
System.out.printf(" Total: $%.2f%n", total);
}
static void printTeam(String teamName, String... members) {
System.out.print("Team " + teamName + ": ");
if (members.length == 0) {
System.out.println("(no members)");
} else {
System.out.println(String.join(", ", members));
}
}
}
Varargs must be the last parameter. Regular params come first.
Build printf-style formatting
Create a method that formats strings with variable placeholders.
public class PrintfStyle {
public static void main(String[] args) {
System.out.println("=== printf-Style Formatting ===\n");
// Java's actual printf
System.out.printf("Name: %s, Age: %d%n", "Alice", 30);
System.out.printf("Price: $%.2f%n", 29.99);
System.out.printf("%s scored %d points%n", "Bob", 150);
System.out.println("\n=== Our Simple Format ===");
// Our custom simpleFormat
String msg1 = simpleFormat("Hello, {}!", "World");
System.out.println(msg1);
String msg2 = simpleFormat("{} + {} = {}", 10, 20, 30);
System.out.println(msg2);
String msg3 = simpleFormat("User {} logged in from {}", "alice", "192.168.1.1");
System.out.println(msg3);
System.out.println("\n=== Logging with Format ===");
logf("INFO", "User {} completed task {}", "Bob", "cleanup");
logf("ERROR", "Failed after {} retries", 3);
logf("DEBUG", "Processing {} items from {}", 100, "queue-1");
}
// Custom format function like SLF4J
static String simpleFormat(String template, Object... args) {
String result = template;
for (Object arg : args) {
// Replace first {} with next argument
result = result.replaceFirst("\\{\\}", String.valueOf(arg));
}
return result;
}
// Logging with formatting
static void logf(String level, String template, Object... args) {
String message = simpleFormat(template, args);
System.out.println("[" + level + "] " + message);
}
}
String.format() and printf() use varargs for their flexible APIs.
Pass an array to varargs
Arrays can be passed directly to varargs methods.
import java.util.Arrays;
public class ArrayVsVarargs {
public static void main(String[] args) {
System.out.println("=== Arrays and Varargs ===\n");
// Call with individual arguments (normal varargs)
printItems("apple", "banana", "cherry");
// Call with existing array
String[] fruits = {"orange", "grape", "mango"};
printItems(fruits); // Array passed directly!
System.out.println("\n=== Creating Arrays ===");
// Traditional array creation
int[] arr1 = new int[]{1, 2, 3};
// Using varargs-based method
int[] arr2 = createArray(4, 5, 6);
System.out.println("arr1: " + Arrays.toString(arr1));
System.out.println("arr2: " + Arrays.toString(arr2));
System.out.println("\n=== Arrays.asList (varargs) ===");
var list = Arrays.asList("x", "y", "z");
System.out.println("List: " + list);
// Also works with array
String[] letters = {"a", "b", "c"};
var list2 = Arrays.asList(letters);
System.out.println("List from array: " + list2);
}
static void printItems(String... items) {
System.out.println("Received " + items.length + " items:");
for (String item : items) {
System.out.println(" - " + item);
}
}
// Return array from varargs
static int[] createArray(int... values) {
return values; // values IS the array!
}
}
Varargs and arrays are interchangeable at the call site.
Exercise: VarargsOverload.java
Explore overloading ambiguity with varargs