Java method overloading, varargs, and pass by value

Declare several methods with the same name and see what a method can and cannot change.

Java
class Main {
  static int sum(int a, int b) {
    return a + b;
  }

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

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

  static void bump(int x) {
    x++;
  }

  static void bumpAll(int[] values) {
    for (int i = 0; i < values.length; i++) {
      values[i]++;
    }
  }

  public static void main(String[] args) {
    System.out.println(sum(2, 3));
    System.out.println(sum(2.5, 3.0));
    System.out.println(sum(1, 2, 3, 4, 5));

    int n = 10;
    bump(n);
    int[] data = {1, 2, 3};
    bumpAll(data);
    System.out.println(n + " " + data[0] + data[1] + data[2]);
  }
}
Output
5
5.5
15
10 234

Explanation

Overloading lets several methods share a name if their parameter lists differ. The compiler picks the one that fits the argument types. A varargs parameter, written int..., accepts any number of arguments and is seen inside the method as an array.

Java always passes arguments by value. A method that receives an int gets a copy, so changing it does not affect the caller. A method that receives an array gets a copy of the reference, so it can change the elements the caller can see, but it cannot make the caller's variable point to a different array.

Explore the dry run
Guided walkthroughReady
1class Main {
2 static int sum(int a, int b) {
3 return a + b;
4 }
5
6 static double sum(double a, double b) {
7 return a + b;
8 }
9
10 static int sum(int... values) {
11 int total = 0;
12 for (int v : values) {
13 total += v;
14 }
15 return total;
16 }
17
18 static void bump(int x) {
19 x++;
20 }
21
22 static void bumpAll(int[] values) {
23 for (int i = 0; i < values.length; i++) {
24 values[i]++;
25 }
26 }
27
28 public static void main(String[] args) {
29 System.out.println(sum(2, 3));
30 System.out.println(sum(2.5, 3.0));
31 System.out.println(sum(1, 2, 3, 4, 5));
32
33 int n = 10;
34 bump(n);
35 int[] data = {1, 2, 3};
36 bumpAll(data);
37 System.out.println(n + " " + data[0] + data[1] + data[2]);
38 }
39}

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
Same name, different parameter types: an overload.—
—
A varargs method: values is an int[] inside the method.—
—
Two ints select the first overload.—
5
Two doubles select the second overload.—
5
5.5
Five ints select the varargs version.—
5
5.5
15
bump receives a copy of n, so the caller's n is unchanged.n = 10
5
5.5
15
bumpAll receives a copy of the reference, so the shared array's elements change.data = [2, 3, 4]
5
5.5
15
n is still 10 and the array holds 2, 3, 4.data = [2, 3, 4]
5
5.5
15
10 234

Cost and common mistakes

O(1) for the two-argument overloads, O(k) for k varargs.

  • Overloads that differ only in the return type are not allowed.
  • If two overloads could both apply, the most specific one wins, and an ambiguous call is a compile error.
  • The expression n + " " + data[0] + ... builds a string left to right, so the three elements are appended as text, not added.

Try it yourself

What does sum() with no arguments return?

Reveal answer and reasoning

0, because the varargs array is empty and the loop adds nothing.

Further reading