SyntaxStudy
Sign Up
Java Varargs, Recursion, and Method Best Practices
Java Beginner 1 min read

Varargs, Recursion, and Method Best Practices

Varargs (variable-length arguments) allow a method to accept any number of arguments of a given type. Inside the method, the vararg parameter behaves as an array. A vararg must be the last parameter in the method signature, and there can be only one per method. Under the hood, the compiler wraps the arguments in an array, so calling a vararg method with no arguments is valid and results in an empty array. Recursion is a technique where a method calls itself to solve a smaller instance of the same problem. Every recursive method needs a base case that terminates the recursion. Classic examples include factorial, Fibonacci, and binary search. Deep recursion can cause StackOverflowError because each call frame consumes stack space. Tail-recursive algorithms can sometimes be rewritten as loops for better performance. Best practices for method design include keeping methods short and focused (the Single Responsibility Principle), choosing descriptive names that convey intent, minimising the number of parameters (prefer a parameter object when there are many), avoiding side effects where possible, and documenting non-obvious behaviour with Javadoc comments.
Example
import java.util.Arrays;

public class VarargsAndRecursion {

    // Varargs: accept any number of ints
    static int sum(int... numbers) {
        int total = 0;
        for (int n : numbers) total += n;
        return total;
    }

    // Varargs mixed with regular parameters
    static void log(String level, String... messages) {
        for (String msg : messages) {
            System.out.printf("[%s] %s%n", level, msg);
        }
    }

    // Recursion: factorial
    static long factorial(int n) {
        if (n <= 1) return 1;           // base case
        return n * factorial(n - 1);    // recursive case
    }

    // Recursion: Fibonacci (with memoisation to avoid exponential time)
    private static long[] memo = new long[50];

    static long fib(int n) {
        if (n <= 1) return n;
        if (memo[n] != 0) return memo[n];
        memo[n] = fib(n - 1) + fib(n - 2);
        return memo[n];
    }

    // Recursion: binary search
    static int binarySearch(int[] arr, int target, int lo, int hi) {
        if (lo > hi) return -1;
        int mid = lo + (hi - lo) / 2;
        if (arr[mid] == target) return mid;
        if (arr[mid] < target)  return binarySearch(arr, target, mid + 1, hi);
        return binarySearch(arr, target, lo, mid - 1);
    }

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

        log("INFO", "Server started", "Listening on port 8080");
        log("ERROR", "Database connection failed");

        for (int i = 0; i <= 10; i++) {
            System.out.printf("%d! = %d%n", i, factorial(i));
        }

        System.out.print("Fibonacci: ");
        for (int i = 0; i < 10; i++) System.out.print(fib(i) + " ");
        System.out.println();

        int[] sorted = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91};
        int idx = binarySearch(sorted, 23, 0, sorted.length - 1);
        System.out.println("Found 23 at index: " + idx);
    }
}