Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Java Method Parameters: Varargs, Overloading, and Recursion

Tech 1

Variable Arguments (Varargs)

Since JDK 1.5, when defining a method, if the type of parameters is determined but the number of parameters is uncertain, you can use variable arguments. The syntax for varargs is:

[modifier] returnType methodName([non-vararg parameter list,] parameterType... parameterName) { }

Characteristics and rules of varargs:

  1. A method can have at most one varargs parameter.
  2. If a method contains a varargs parameter, it must be the last in the parameter list.
  3. Inside the method, the varargs parameter is used as an array.
  4. The syntax is essentially equivalent to:
    [modifier] returnType methodName([non-vararg parameter list,] parameterType[] parameterName) { }
    
    However, the first form is more flexible because you can pass an array or individual elements driectly.

1. Method with Only Varargs

Example: Calculate the sum of n integers.

public class NumberTools {
    // Method using array parameter (must pass array)
    int total(int[] nums) {
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        return sum;
    }

    // Method using varargs (can pass array or individual elements)
    int sum(int... nums) {
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        return sum;
    }
}
public class TestVarParam {
    public static void main(String[] args) {
        NumberTools tools = new NumberTools();

        // Using varargs method
        System.out.println(tools.sum());           // 0 arguments
        System.out.println(tools.sum(5));          // 1 argument
        System.out.println(tools.sum(5, 6, 2, 4)); // 4 arguments
        System.out.println(tools.sum(new int[]{5, 6, 2, 4})); // array argument

        System.out.println("------------------------------------");

        // Using array method
        System.out.println(tools.total(new int[]{}));            // empty array
        System.out.println(tools.total(new int[]{5}));           // single element
        System.out.println(tools.total(new int[]{5, 6, 2, 4})); // array
    }
}

2. Method with Both Non-Varargs and Varargs

  • The non-varargs part must receive arguments of the corresponding type and count.
  • The varargs part can receive 0 to n arguments of the specified type or an array of that type.

Example: Concatenate strings with a separator.

public class StringTools {
    String concat(char separator, String... args) {
        String result = "";
        for (int i = 0; i < args.length; i++) {
            if (i == 0) {
                result += args[i];
            } else {
                result += separator + args[i];
            }
        }
        return result;
    }
}
public class StringToolsTest {
    public static void main(String[] args) {
        StringTools tools = new StringTools();

        System.out.println(tools.concat('-'));                    // ""
        System.out.println(tools.concat('-', "hello"));          // "hello"
        System.out.println(tools.concat('-', "hello", "world")); // "hello-world"
        System.out.println(tools.concat('-', "hello", "world", "java")); // "hello-world-java"
    }
}

Command-Line Arguments (Optional)

Arguments passed via the command line to the main method's String[] args are called command-line arguments.

public class TestCommandParam {
    public static void main(String[] args) {
        System.out.println(args);
        System.out.println(args.length);

        for (int i = 0; i < args.length; i++) {
            System.out.println("Argument " + (i + 1) + " value: " + args[i]);
        }
    }
}

Command-line execution:

java TestCommandParam
java TestCommandParam 1 2 3
java TestCommandParam hello world

Parameter Passing Mechanism

How are arguments passsed to parameters? Does the modification of a parameter affect the argument?

  • When a parameter is of a primitive type, changing the parameter's value does not affect the original argument.
  • When a parameter is of a reference type, changing the parameter's reference (e.g., assigning a new object) does not affect the original argument, but modifying the object's internal data (e.g., array elements or object fields) does affect the original object.
    • Note: Special types like String and Integer may behave unexpectedly.

1. Primitive Type Parameter

Example: Swap two integer values.

public class PrimitiveTypeParam {
    void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }

    public static void main(String[] args) {
        PrimitiveTypeParam tools = new PrimitiveTypeParam();
        int x = 1, y = 2;
        System.out.println("Before swap: x = " + x + ", y = " + y); // 1,2
        tools.swap(x, y);
        System.out.println("After swap: x = " + x + ", y = " + y);  // 1,2 (unchanged)
    }
}

2. Array Type Parameter

public class ArrayTypeParam {
    // Sorts the array (modifies the original)
    void sort(int[] arr) {
        for (int i = 1; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    // Prints array elements (does not modify)
    void iterate(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        ArrayTypeParam tools = new ArrayTypeParam();
        int[] nums = {4, 3, 1, 6, 7};

        System.out.println("Before sorting:");
        tools.iterate(nums);

        tools.sort(nums); // modifies nums

        System.out.println("After sorting:");
        tools.iterate(nums);
    }
}

3. Reference Type Parameter

public class ReferenceTypeParam {
    void swap(MyData my) {
        int temp = my.x;
        my.x = my.y;
        my.y = temp;
    }

    public static void main(String[] args) {
        ReferenceTypeParam tools = new ReferenceTypeParam();
        MyData data = new MyData();
        data.x = 1;
        data.y = 2;

        System.out.println("Before swap: x = " + data.x + ", y = " + data.y); // 1,2
        tools.swap(data);
        System.out.println("After swap: x = " + data.x + ", y = " + data.y);  // 2,1 (changed)
    }
}

class MyData {
    int x;
    int y;
}

4. Parameter Assigned to New Object

public class AssignNewObjectToFormalParam {
    void swap(MyData my) {
        my = new MyData(); // now my points to a new object
        int temp = my.x;
        my.x = my.y;
        my.y = temp;
    }

    public static void main(String[] args) {
        AssignNewObjectToFormalParam tools = new AssignNewObjectToFormalParam();
        MyData data = new MyData();
        data.x = 1;
        data.y = 2;

        System.out.println("Before swap: x = " + data.x + ", y = " + data.y); // 1,2
        tools.swap(data);
        System.out.println("After swap: x = " + data.x + ", y = " + data.y);  // 1,2 (unchanged)
    }
}

Method Overloading

Method overloading allows multiple methods with the same name but diffferent parameter lists in the same class. It does not depend on the modifier or return type.

  • Parameter list differences: different number of parameters, different types, or different order (rare and not recommended).
  • The JVM selects the appropriate method based on the argument list.
    • First, look for an exact match.
    • Then, look for compatible matches. If multiple compatible methods exist, ambiguity occurs.

Example: Overload methods to find the maximum value.

public class MathTools {
    // Maximum of two integers
    public int max(int a, int b) {
        return a > b ? a : b;
    }

    // Maximum of two doubles
    public double max(double a, double b) {
        return a > b ? a : b;
    }

    // Maximum of three integers
    public int max(int a, int b, int c) {
        return max(max(a, b), c);
    }

    // Maximum of n integers
    public int max(int... nums) {
        int max = nums[0]; // assumes at least one argument
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > max) {
                max = nums[i];
            }
        }
        return max;
    }
}

1. Exact Match

public class MethodOverloadMostMatch {
    public static void main(String[] args) {
        MathTools tools = new MathTools();

        System.out.println(tools.max(5, 3));      // int, int
        System.out.println(tools.max(5, 3, 8));   // int, int, int
        System.out.println(tools.max(5.7, 2.5));  // double, double
    }
}

2. Compatible Match

public class MethodOverloadMostCompatible {
    public static void main(String[] args) {
        MathTools tools = new MathTools();

        System.out.println(tools.max(5.7, 9));       // double, int -> compatible with double, double
        System.out.println(tools.max(5, 6, 8, 3));   // varargs
        // System.out.println(tools.max(5.7, 9.2, 6.9)); // no compatible method (three doubles)
    }
}

Recursive Method Calls

Recursion occurs when a method calls itself. There are two types: direct recursion (A calls A) and indirect recursion (A calls B, B calls C, C calls A).

Important:

  • Recursion must have a base condition to terminate; otherwise, a stack overflow occurs.
  • Even with a base condition, deep recursion can cause inefficiency or stack overflow. Use loops instead when possible.

Example: Calculate the nth Fibonacci number. Fibonacci sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... Formula: f(n) = f(n-2) + f(n-1), with f(1) = f(2) = 1.

public class FibonacciTest {
    public static void main(String[] args) {
        FibonacciTest t = new FibonacciTest();

        for (int i = 1; i <= 10; i++) {
            System.out.println("Fibonacci number " + i + ": " + t.f(i));
        }
        System.out.println(t.f(20)); // 6765
    }

    int f(int n) {
        if (n <= 1) return 1; // handle n < 1
        if (n == 1 || n == 2) return 1;
        return f(n - 2) + f(n - 1);
    }
}

Object Arrays

An object array stores references to objects. The array itself must be created first (specifying length), then each element object must be created individually; otherwise, default elements are null, causing a NullPointerException.

Example: Define a Rectangle class, then create an array of Rectangle objects and display their info.

public class Rectangle {
    double length;
    double width;

    double area() {
        return length * width;
    }

    double perimeter() {
        return 2 * (length + width);
    }

    String getInfo() {
        return "Length: " + length +
               ", Width: " + width +
               ", Area: " + area() +
               ", Perimeter: " + perimeter();
    }
}
public class ObjectArrayTest {
    public static void main(String[] args) {
        // Declare and create a Rectangle array with 3 elements
        Rectangle[] array = new Rectangle[3];

        for (int i = 0; i < array.length; i++) {
            array[i] = new Rectangle();
            array[i].length = (i + 1) * 10;
            array[i].width = (2 * i + 1) * 5;

            System.out.println(array[i].getInfo());
        }
    }
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.