2

I've learned that in Java, arrays are passed by reference, meaning that they can be modified within functions. However, I recently came across this piece of code that confused me, because it seems to show inconsistent behavior.

import java.io.*;
import java.util.*;

public class TestProgram {

    public static void fMethod(int[] f){
        f[0] = 9;
        f[1] = 7;
        f = new int[4];
    }

    public static void main(String[] args){
        int[] fParam = new int[3];
        fMethod(fParam);
        System.out.println(Arrays.toString(fParam)); // prints [9, 7, 0]
    }
}

Because the function fMethod() seems to reset f to a new int[4] at the end, I expected to see [0, 0, 0, 0] printed to the console. However, it seems that only the f[0] = 9 and the f[1] = 7 lines were actually executed, while the last line was ignored. I find this strange. Can somebody please point me in the right direction?

  • 4
    Does [this](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) answer your question? To expand, Java is pass-by-value only. Arrays are objects, and you can modify objects, given their reference. Modification of the reference passed into a method won't affect anything outside, though. – Andrew Vershinin Jan 19 '21 at 23:37
  • 1
    @AndrewVershinin So would it be correct to say that any direct "re-pointing" of a reference in a function scope would be ignored by the compiler? – JavaIsAProgrammingLanguageLol Jan 19 '21 at 23:41
  • 2
    It's not ignored. You're creating a new, locally scoped variable called `f` and shadowing the input parameter. Meanwhile, `main` method still maintains a reference to the `fParam` array passed into the method – OneCricketeer Jan 19 '21 at 23:49
  • 1
    Re your statement "arrays are passed by reference" : no, this is incorrect. Java only supports 'pass by value' and even references are passed by value. If you pass a reference as a parameter to a method, the method received a copy of that reference. Trying to change the copy of that reference to point to something else only changes the copy within the scope of that method, it doesn't change the original reference that was passed in – Kevin Hooke Jan 19 '21 at 23:55

2 Answers2

3

Remember, that:

In Java, everything is passed by value.

and in case of objects (arrays are also objects), address of the object, a value, is being copied into another variable.

In your code, int[] f is a local variable (scoped in a method), which initially refers to the original array and:

f[0] = 9;
f[1] = 7;

changes original array.

However, then you assign a new array object to f and you, eventually, discard that object entirely (as you don't return anything).

As long as f refers to the first array, it alters that array, and therefore, it only changes first two elements of it. After that, f refers to something else.

In your main method, though, fParam still refers to the previous array object and you print that object, 3rd element of which, is an integer array's default value, 0.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
2

Within fMethod, you get the array passed as variable f. As long as you modify the content of the variable, it will actually change your reference. On line 3 of your method: f = new int[4] you assign a new array to the variable f. This means you overwrite the reference the variable f holds by assigning a new value, so any modifications afterwards to the array happen to the new assigned array. If you would introduce a class variable instead and pass it to the method, your application would act as you'd expect it to.

papalulu
  • 78
  • 6