1. In "amethod" first a method local variable i is set to 99 2. A new ValHold object v is created with a field value for i = 10. This field value is changed to 30 in the next statement. 3. You then call the "another" method, by passing a reference to the v object and the value of i (99). Note that v.i at this time will still be 30. 4. In "another" method you set the method local i = 0, and v.i = 20. 5. Then create a new ValHold object vh with vh.i = 10 6. Change the object reference v to point to vh (locally). So, before the last two print statements, both v and vh will be referring (locally) to the new object you just created above with a field value of i being 10. However, the original object v that was created in "amethod" still out there in the call stack. 7. When you print v.i, as expected, prints 10 8. When you print i, prints the value of local i, i.e., 0 9. Next, the execution resumes in "amethod" (with the print statement). 10. Since you had modified the field value of v.i in another method, it prints 20.
From Khalid and Rolf's book
3.18 Passing Primitive Data Values When the actual parameter is a variable of a primitive data type, the value of the variable 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. | 3.19 Passing Object Reference Values If an actual parameter is a reference to an object, then the reference value is passed. This means that both the actual parameter and the formal parameter are aliases to the object denoted by this reference value during the invocation of the method. In particular, this implies that changes made to the object via the formal parameter will be apparent after the call returns. The actual parameter expression must evaluate to an object reference before the reference value can be passed. |