Concepts / Writing Methods With Parameters

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.

  • Programming

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?

java
Notes on the code
  • 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.
java
Output
5.0
3.0
Notes on the code
  • 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.
Listed values2.0, 4.0, 6.0, 8.0Array argumentone value for the parametervalues parameterarray inside the methodLoop bodyreads each elementgathered intoreceived asread by
When I pass several values, where does the array come from, and how do those values flow into the single parameter the method receives?

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
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

Definition

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.

Separate valuesaverage(2.0, 4.0, 6.0, 8.0)Values arraybuilt from the listedvaluesOne arrayaverage(data)Values arrayarray passed as theargumentarrives asarrives as
When I call the method with separate values and when I call it with one array, what actually arrives at the method, and are those two calls the same from the method's point of view?

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.

values[0]2.0values[1]4.0values[2]6.0values[3]8.0
Inside the method, how are the individual arguments stored and accessed, and how do the positions index 0, 1, 2 map to the values that were passed?

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.

java
Notes on the code
  • 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.

Values already inan array?Pass the arrayaverage(data)List the valuesaverage(2.0, 4.0, 6.0, 8.0)yesno
Given data I already hold in an array versus values I list directly, which calling form should I pick and why?

Mistakes With Variable Arity Calls

  • Common mistake

    Unpacking an array into separate values before calling the method

    What it looks like

    average(data[0], data[1], data[2], data[3]) when data already holds the four values

    Why it fails

    The 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 instead
    Pass the array itself: average(data).
  • Common mistake

    Assuming the two forms behave differently inside the method

    What it looks like

    Believing average(data) and average(2.0, 4.0, 6.0, 8.0) need separate code paths

    Why it fails

    Both calls reach the method through the same variable arity parameter, which is an array, so the method body is identical.

    Do this instead

    Write 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 like

    Writing values + 1 inside the body as if values held one number

    Why it fails

    Inside the method the parameter is an array, so it holds several values and must be read by position or by a loop.

    Do this instead

    Read elements with values[0] or loop over values with a for-each statement.

Practice: Choose the Calling Form

EASY

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.