Passing Primitive Data Values
An actual parameter is an expression that is evaluated first, with the resulting value then being assigned to the corresponding formal parameter at method invocation. The use of this value in the method has no influence on the actual parameter. In particular, when the actual parameter is a variable of a primitive data type, the value of the variable from the stack is copied to the formal parameter at method invocation. Since formal parameters are local to the method, any changes made to the formal parameter will not be reflected in the actual parameter after the call completes.
Legal type conversions between actual parameters and formal parameters of primitive data types are summarized here from Table 2.17, p. 47:
- Primitive widening conversion
- Unboxing conversion, followed by an optional widening primitive conversion
These conversions are illustrated by invoking the following method
static void doIt(long i) { /* … */ }
with the following code:
Integer intRef = 34;
Long longRef = 34L;
doIt(34); // (1) Primitive widening conversion: long <– int
doIt(longRef); // (2) Unboxing: long <– Long
doIt(intRef); // (3) Unboxing, followed by primitive widening conversion:
// long <– int <– Integer
However, for parameter passing, there are no implicit narrowing conversions for integer constant expressions (§2.4, p. 48).
Example 3.10 Passing Primitive Values
public class CustomerOne {
public static void main (String[] args) {
PizzaFactory pizzaHouse = new PizzaFactory();
int pricePrPizza = 15;
System.out.println(“Value of pricePrPizza before call: ” + pricePrPizza);
double totPrice = pizzaHouse.calcPrice(4, pricePrPizza); // (1)
System.out.println(“Value of pricePrPizza after call: ” + pricePrPizza);
}
}
class PizzaFactory {
public double calcPrice(int numberOfPizzas, double pizzaPrice) { // (2)
pizzaPrice = pizzaPrice / 2.0; // Changes price.
System.out.println(“Changed pizza price in the method: ” + pizzaPrice);
return numberOfPizzas * pizzaPrice;
}
}
Output from the program:
Value of pricePrPizza before call: 15
Changed pizza price in the method: 7.5
Value of pricePrPizza after call: 15
In Example 3.10, the method calcPrice() is defined in the class PizzaFactory at (2). It is called from the CustomerOne.main() method at (1). The value of the first actual parameter, 4, is copied to the int formal parameter numberOfPizzas. Note that the second actual parameter pricePrPizza is of the type int, while the corresponding formal parameter pizzaPrice is of the type double. Before the value of the actual parameter pricePrPizza is copied to the formal parameter pizzaPrice, it is implicitly widened to a double. The passing of primitive values is illustrated in Figure 3.2.
Figure 3.2 Parameter Passing: Primitive Data Values
The value of the formal parameter pizzaPrice is changed in the calcPrice() method, but this does not affect the value of the actual parameter pricePrPizza on return. It still has the value 15. The bottom line is that the formal parameter is a local variable, and changing its value does not affect the value of the actual parameter.