Java, pass-by-value, reference variables
There's an extended discussion of how Java passes variables at an earlier question "Is Java pass by reference?". Java really passes object references by value.
In your code, the references for the arrays (which are objects) are passed into calculate()
. These references are passed by value, which means that any changes to the values of b
and c
are visible only within the method (they are really just a copy of s_ccc
and t_ccc
). That's why t_ccc
in main()
was never affected.
To reinforce this concept, some programmers declare the method parameters as final
variables:
public static void calculate(final int[] b, final int[] c)
Now, the compiler won't even allow you to change the values of b
or c
. Of course, the downside of this is that you can no longer manipulate them conveniently within your method.
Here's a simple way to understand it.
Java always passes copies of arguments. If the argument is a primitive type (e.g. an integer), then the called method gets a copy of the primitive value. If the argument is a reference type, then the called method gets a copy of the reference (not a copy of the thing referred to).
When your main
method begins, each of s_ccc
and t_ccc
refers to a distinct array.
This is the situation, where parentheses indicate variables and square brackets indicate the actual array structures:
(s_ccc) ---> [7]
(t_ccc) ---> [7]
Assuming that you meant calculate(s_ccc, t_ccc)
, then at the beginning of the calculate
method:
(s_ccc) ---> [7] <---(b)
(t_ccc) ---> [7] <---(c)
Locals b
and c
are copies of globals s_ccc
and t_ccc
respectively.
Still within calculcate
, after b[0] = b[0] + 9
has completed:
(s_ccc) ---> [16] <---(b)
(t_ccc) ---> [7] <---(c)
The zero (only) position in the array referred to by b
has been modified.
The assignment c = b
within calculate
produces this situation:
(s_ccc) ---> [16] <---(b)
^------(c)
(t_ccc) ---> [7]
The local reference variable c
, now contains the same reference as b
. That has no effect on the global reference variable t_ccc
, which still refers to the same array as before.
When calculate
exits, its local variables (on the right-hand side of the diagrams) disappear. The global variables (on the left-hand side) were not used in calculate
, so they are unaffected. The final situation is:
(s_ccc) ---> [16]
(t_ccc) ---> [7]
Neither c_ccc
nor t_ccc
were changed; each still refers to the same array as before calculate
. Calling calculate
changed the content of the array referenced by s_ccc
, using a copied reference to that array (in b
).
Local variable c
started as a copy of t_ccc
and was manipulated within calculate
, but that changed neither t_ccc
itself nor it's referenced data.
The method receives variables by value. Those values can't be changed (as far as the caller of the method sees), but the values contained within them can (if it's an object, or as in this case, an array).
So when you change the value b[0] inside the array, the change can be seen outside the method. However the line
c = b;
will change the value of c inside the method, but that change will not be seen outside the method, since the value of c was passed by value.
The line calculate(s_ccc, s_ccc);
indicates you're not actually doing anything to t_ccc.
However, should this line have read calculate(s_ccc, t_ccc);
than the effect remains the same.
This is due to the fact that you're assigning a new value to c here: c = b;
When assigning a new value to a reference argument the reference is lost.
This is the difference between altering a by reference variable and assigning a new value.