Passing Arrays to Methods

This section demonstrates how to pass arrays and array elements as arguments to methods. At the end of the section, we discuss how all types of arguments are passed to methods. To pass an array argument to a method, specify the name of the array without any brackets. For example, if array hourlyTemperatures is declared as

double hourlyTemperatures[] = new double[ 24 ];

then the method call

modifyArray( hourlyTemperatures );

passes the reference of array hourlyTemperatures to method modifyArray. Every array object "knows" its own length (via its length field). Thus, when we pass an array object's reference into a method, we need not pass the array length as an additional argument.

For a method to receive an array reference through a method call, the method's parameter list must specify an array parameter. For example, the method header for method modifyArray might be written as

void modifyArray( int b[] )

indicating that modifyArray receives the reference of an integer array in parameter b. The method call passes array hourlyTemperature's reference, so when the called method uses the array variable b, it refers to the same array object as hourlyTemperatures in the calling method.

When an argument to a method is an entire array or an individual array element of a reference type, the called method receives a copy of the reference. However, when an argument to a method is an individual array element of a primitive type, the called method receives a copy of the element's value. Such primitive values are called scalars or scalar quantities. To pass an individual array element to a method, use the indexed name of the array as an argument in the method call.

Figure 7.13 demonstrates the difference between passing an entire array and passing a primitive-type array element to a method. The enhanced for statement at lines 1617 outputs the five elements of array (an array of int values). Line 19 invokes method modifyArray, passing array as an argument. Method modifyArray (lines 3640) receives a copy of array's reference and uses the reference to multiply each of array's elements by 2. To prove that array's elements were modified, the for statement at lines 2324 outputs the five elements of array again. As the output shows, method modifyArray doubled the value of each element.

Figure 7.13. Passing arrays and individual array elements to methods.

(This item is displayed on pages 304 - 305 in the print version)

1 // Fig. 7.13: PassArray.java 2 // Passing arrays and individual array elements to methods. 3 4 public class PassArray 5 { 6 // main creates array and calls modifyArray and modifyElement 7 public static void main( String args[] ) 8 { 9 int array[] = { 1, 2, 3, 4, 5 }; 10 11 System.out.println( 12 "Effects of passing reference to entire array: " + 13 "The values of the original array are:" ); 14 15 // output original array elements 16 for ( int value : array ) 17 System.out.printf( " %d", value ); 18 19 modifyArray( array ); // pass array reference 20 System.out.println( " The values of the modified array are:" ); 21 22 // output modified array elements 23 for ( int value : array ) 24 System.out.printf( " %d", value ); 25 26 System.out.printf( 27 " Effects of passing array element value: " + 28 "array[3] before modifyElement: %d ", array[ 3 ] ); 29 30 modifyElement( array[ 3 ] ); // attempt to modify array[ 3 ] 31 System.out.printf( 32 "array[3] after modifyElement: %d ", array[ 3 ] ); 33 } // end main 34 35 // multiply each element of an array by 2 36 public static void modifyArray( int array2[] ) 37 { 38 for ( int counter = 0; counter < array2.length; counter++ ) 39 array2[ counter ] *= 2; 40 } // end method modifyArray 41 42 // multiply argument by 2 43 public static void modifyElement( int element ) 44 { 45 element *= 2; 46 System.out.printf( 47 "Value of element in modifyElement: %d ", element ); 48 } // end method modifyElement 49 } // end class PassArray  

Effects of passing reference to entire array: The values of the original array are: 1 2 3 4 5 The values of the modified array are: 2 4 6 8 10 Effects of passing array element value: array[3] before modifyElement: 8 Value of element in modifyElement: 16 array[3] after modifyElement: 8  

Figure 7.13 next demonstrates that when a copy of an individual primitive-type array element is passed to a method, modifying the copy in the called method does not affect the original value of that element in the calling method's array. To show the value of array[ 3 ] before invoking method modifyElement, lines 2628 output the value of array[ 3 ] (8). Line 30 calls method modifyElement and passes array[ 3 ] as an argument. Remember that array[ 3 ] is actually one int value (8) in array. Therefore, the program passes a copy of the value of array[ 3 ]. Method modifyElement (lines 4348) multiplies the value received as an argument by 2, stores the result in its parameter element, then outputs the value of element (16). Since method parameters, like local variables, cease to exist when the method in which they are declared completes execution, the method parameter element is destroyed when method modifyElement terminates. Thus, when the program returns control to main, lines 3132 output the unmodified value of array[ 3 ] (i.e., 8).

Notes on Passing Arguments to Methods

The preceding example demonstrated the different ways that arrays and primitive-type array elements are passed as arguments to methods. We now take a closer look at how arguments in general are passed to methods. Two ways to pass arguments in method calls in many programming languages are pass-by-value and pass-by-reference (also called call-by-value and call-by-reference). When an argument is passed by value, a copy of the argument's value is passed to the called method. The called method works exclusively with the copy. Changes to the called method's copy do not affect the original variable's value in the caller.

When an argument is passed by reference, the called method can access the argument's value in the caller directly and modify that data, if necessary. Pass-by-reference improves performance by eliminating the need to copy possibly large amounts of data.

Unlike some other languages, Java does not allow programmers to choose pass-by-value or pass-by-referenceall arguments are passed by value. A method call can pass two types of values to a methodcopies of primitive values (e.g., values of type int and double) and copies of references to objects (including references to arrays). Objects themselves cannot be passed to methods. When a method modifies a primitive-type parameter, changes to the parameter have no effect on the original argument value in the calling method. For example, when line 30 in main of Fig. 7.13 passes array[ 3 ] to method modifyElement, the statement in line 45 that doubles the value of parameter element has no effect on the value of array[ 3 ] in main. This is also true for reference-type parameters. If you modify a reference-type parameter by assigning it the reference of another object, the parameter refers to the new object, but the reference stored in the caller's variable still refers to the original object.

Although an object's reference is passed by value, a method can still interact with the referenced object by calling its public methods using the copy of the object's reference. Since the reference stored in the parameter is a copy of the reference that was passed as an argument, the parameter in the called method and the argument in the calling method refer to the same object in memory. For example, in Fig. 7.13, both parameter array2 in method modifyArray and variable array in main refer to the same array object in memory. Any changes made using the parameter array2 are carried out on the same object that is referenced by the variable that was passed as an argument in the calling method. In Fig. 7.13, the changes made in modifyArray using array2 affect the contents of the array object referenced by array in main. Thus, with a reference to an object, the called method can manipulate the caller's object directly.

Performance Tip 7.1

Passing arrays by reference makes sense for performance reasons. If arrays were passed by value, a copy of each element would be passed. For large, frequently passed arrays, this would waste time and consume considerable storage for the copies of the arrays.

Категории