Writing Methods With Parameters
A single array may be passed to a variable arity method in place of a list of separate values, and the call is legal.
A Question About Values Already in an Array
Imagine you have written a method designed to take any number of numbers and compute their average. A caller can list the values one by one. But suppose the values already sit together in an array, perhaps because they were read from a file or collected in a loop. Must the caller unpack that array into separate values before making the call? The answer shapes how you will write and read every call to a method of this kind.
This article answers that question. The key fact is that a method can be written to accept a variable number of arguments, and that a caller has two legal ways to supply them. You can list the individual values, or you can pass one array that already holds those values. The method body is the same in both cases, so understanding why will also show you how to read these methods.
Tracing One Complete Call
Before looking at the rules in general, it helps to watch one complete call from start to finish. The example uses an averaging method that accepts any number of double values. The caller holds its data in an array. Read each step and ask two questions: what does the caller pass, and what does the method receive?
- The three dots after double mark the parameter as a variable arity parameter.
- Inside the body, values is used like any other array: it has a length and its elements can be read in order.
5.0
3.0- The first call supplies one array whose four elements are averaged.
- The second call supplies two separate values, and they are averaged in the same way.
The diagram traces a single path. The values reach the call, they arrive inside the method as one parameter, and the method reads the elements of that parameter to produce a result. The walkthrough in the code above describes the same path, so a reader who follows either one should reach the same conclusion. Both calls produce the same kind of result because the values they supply are the same.
Predict Before Checking the Result
What do you think happens?
If data holds 2.0, 4.0, 6.0, 8.0, what does average(data) return, and what would average(2.0, 4.0, 6.0, 8.0) return?
Reveal answer
Both calls return 5.0.
The array call supplies the four values as one argument, and the separate-values call supplies the same four values in the call itself. The method averages the same four numbers in both cases, so the sum is 20.0 and dividing by the length 4 gives 5.0.
Why a Single Array Is a Legal Argument
A variable arity parameter is the parameter that can accept any number of arguments. What matters most is what it becomes once the call is made: inside the method body, the variable arity parameter behaves as an array.
This is why a single array is a legal argument. The method was declared to receive its variable arity parameter as an array, so an argument that is already an array fits that parameter directly. The caller is not forced to take the values out of the array and list them again. Whether the caller listed the values one by one or handed over an existing array, the method can work with the values through that array.
Two calls, one method. The method accepts both forms because the parameter it declares is an array, and both forms supply values in the form that parameter expects. The method body does not need to know which form was used, because by the time the code inside runs, the values are available through the array.
What the Parameter Looks Like Inside the Body
Once the call is made, the method sees one array. Each value is reached through a position: index 0 is the first value passed, index 1 is the second, and so on up to the last position. The method reads those positions the way it would read any array, which is why the loop in the averaging method can walk through every value in order.
Because the parameter is an array, the length of the array is the number of values the method received. This is why the averaging method divides by values.length rather than by a fixed count. The same method therefore works for two values, four values, or any other number of values.
Polygon Points as Array Elements
The same idea scales to more complicated parameter types. Consider a method that draws a polygon through any number of points, where each point is an object with two integer instance variables, x and y. Such a method has one ordinary parameter, the graphics context used for drawing, plus a variable arity parameter for the points. Inside the method, that parameter is an array of Point objects, so the method can loop over the points in order to connect them.
- The Graphics parameter is ordinary and is listed first.
- The Point... parameter is the variable arity parameter, and inside the body it is an array of Point objects.
Choosing Between Separate Values and One Array
The choice between the two forms follows from how the data already exists. Use separate values when you have a few known numbers that you can name directly in the call. Use one array when the values are stored together, for example because they came from a file or were collected in a loop. Because both forms produce the same method behavior when the values match, you are choosing for readability and convenience rather than for correctness.
Mistakes With Variable Arity Calls
Common mistake Unpacking an array into separate values before calling the method
What it looks likeaverage(data[0], data[1], data[2], data[3]) when data already holds the four values
Why it failsThe array can be passed directly as a single argument, so the manual unpacking adds work and makes the call harder to change if the array length changes.
Do this insteadPass the array itself: average(data).Common mistake Assuming the two forms behave differently inside the method
What it looks likeBelieving average(data) and average(2.0, 4.0, 6.0, 8.0) need separate code paths
Why it failsBoth calls reach the method through the same variable arity parameter, which is an array, so the method body is identical.
Do this insteadWrite the method once and read the values through the array in both cases.
Common mistake Treating the variable arity parameter as a single value
What it looks likeWriting values + 1 inside the body as if values held one number
Why it failsInside the method the parameter is an array, so it holds several values and must be read by position or by a loop.
Do this insteadRead elements with values[0] or loop over values with a for-each statement.
Practice: Choose the Calling Form
A program reads 50 temperature readings from a file into an array named readings. Using the average method described in this article, write the call that computes their average, and explain in one sentence why you chose that form.
Hints
- Ask whether the values already exist together in one place.
- The array can be passed directly as the single argument in the call.
Key Takeaways
- A variable arity parameter accepts any number of arguments, and inside the method body it behaves as an array.
- A caller can pass several individual values or one array that already holds those values, and both forms reach the method through the same parameter.
- A single array is a legal argument because the parameter is declared as an array, so an existing array fits it directly.
- Inside the method, values are read by position, and the array length gives the number of values received.
- Choose separate values for a few known numbers and one array for values already stored together.