Arrays and Indexing
A variable arity method accepts a varying number of actual parameters, and the values for that parameter are placed into an array before the method is called.
A Method That Accepts Any Number of Inputs
Most methods are written with a fixed list of parameters, so every call has to supply exactly that many values. A variable arity method removes that restriction. It is written once, but a caller may pass a different number of actual parameters each time it is invoked. This article answers one question: when a method accepts a varying number of inputs, how does the body of that method actually get hold of them?
The short answer is that the language does not hand the method a loose, unknown collection of values. It packages them into a single structure that the body can inspect. Before reading on, pause and predict what that single structure might be. Then follow one call step by step and check your guess.
Tracing One Call from Start to Finish
Follow a single call. At the call site, the caller writes the actual parameters that correspond to the variable arity parameter. Suppose the caller supplies three values: 4.0, 7.0, and 9.0. When the method is called, the values of all three actual parameters are placed into an array. It is that array, not the three separate values, that is actually passed to the method.
The diagram shows the key point of the whole mechanism. Several separate values at the call site become one array argument. The method therefore receives a single value of array type, and the body has to work with that array to see the individual values. Notice that the method never sees the three values as three separate parameters. It sees one array holding them.
Why the Parameter Looks Like an Ordinary Array
Inside the method body, a variable arity parameter of type T looks like an ordinary parameter of type T[]. The declaration in the method header uses the variable arity form, but once execution is inside the body, the parameter behaves as a plain array of that element type. This is why the body does not need any special machinery to handle a variable count. It uses the same tools it would use on any array: a length, and indexed access to each element.
Think of the variable arity parameter as a container that the language fills at the call site. Its declared type tells the reader that values of type T may be supplied. Its runtime form inside the body is T[], so every operation that works on arrays works on it too.
Reading Arguments with Length and Index
The source uses a method that works with a list of numbers and computes their average as its running example. In the body of that method, the array is named numbers and has type double[]. Two pieces of information come directly from it. The number of actual parameters in the call is numbers.length, and the individual values are numbers[0], numbers[1], and so on, up to the last valid index.
- The header uses the variable arity form; inside the body numbers is an ordinary double[].
numbers.lengthgives the count of actual parameters supplied by the caller.- numbers[i] reads one value by index, starting at zero.
- The loop walks every valid index from 0 up to, but not including, the length.
This body is an original illustration of how the two facts combine. It totals every element by walking the indices from zero up to the length, then divides by the count. Nothing here is new syntax; it is ordinary array code that happens to operate on the array the method received.
6.666666666666667- The caller writes three actual parameters.
- Before the body runs, those three values are placed into one double[] of length 3.
- The body divides the total of the three values by
numbers.length, which is 3.
What do you think happens?
The caller writes average(4.0, 7.0, 9.0). What value does numbers.length have inside the body?
Reveal answer
3
numbers.length is the number of actual parameters supplied in the call. Three values were passed, so the array holds three elements, indexed 0, 1, and 2.
Notice that the length is a property of the array as a whole, not something the caller has to pass separately. Because the count travels with the array, the body can always find out how many values it received without any extra parameter describing the count. That is why the signature needs only the variable arity parameter and nothing else to carry the count.
Calls That Supply No Variable Values
What happens when the caller supplies no values for the variable arity parameter? The same mechanism applies. The values that the caller supplied for that parameter are placed into an array, and in this case there are none to place. The body therefore receives an array whose length reflects zero supplied values. The length check is the way the body detects this situation.
Mistakes Beginners Make with Indexes
Common mistake Treating each supplied value as its own named parameter
What it looks likeWriting the body as if there were a separate variable for the first, second, and third argument
Why it failsThe method receives one array argument. The individual values exist only as elements of that array.
Do this insteadRead the values through the array, using numbers[0], numbers[1], and so on.
Common mistake Looping to the length inclusively
What it looks likefor (int i = 0; i <= numbers.length; i++) total += numbers[i];Why it failsValid indexes run from 0 to length minus 1, so the index equal to the length is out of range.
Do this insteadUse i < numbers.length as the loop condition.
Common mistake Passing a separate count argument alongside the variable values
Why it failsThe count already travels with the array, so a separate count parameter repeats information the body can read from
numbers.length.Do this insteadUse numbers.length to find the number of supplied values.
Practice Reading an Argument List
A method is declared as double average(double... numbers), and a caller writes average(2.0, 4.0, 6.0, 8.0). Without running the code, state the value of numbers.length, the value of numbers[0], and the value of numbers[3]. Then explain which index would be out of range if the loop used i <= numbers.length.
Hints
- Count the actual parameters in the call to find the length.
- Indexes start at zero, so the last valid index is always length minus 1.
- The first element is numbers[0], which holds the first actual parameter.
Modify the average method so that it returns the largest supplied value instead of the average. Use numbers.length to control the loop and numbers[i] to read each value.
Hints
- Start with the first element as the current largest value.
- Loop from index 1 up to
numbers.lengthminus 1.
Key Takeaways for Variable Arity Methods
- 1The actual parameters supplied for a variable arity parameter are placed into an array before the method runs, and that array is the single argument the method receives.
- 2Inside the body, a parameter of type T behaves like an ordinary parameter of type T[], so the usual array tools apply.
- 3The array's length gives the number of actual parameters supplied, and numbers[0], numbers[1], and so on read the individual values.
- 4Because the count travels with the array, no separate count parameter is needed.
At a glance
- A variable arity method receives its varying actual parameters packaged into a single array before the body runs.
- Inside the body, a variable arity parameter of type T looks like an ordinary parameter of type T[].
- The array length gives the count of supplied values, and indexed access such as numbers[0] reads each one.
- The count travels with the array, so the body needs no separate count parameter.