0

Code

public class Foo {

    public static void main(String[] args) {

        //declaring and initializing String variable 'str' with value "outside"
        String str = "main";

        //declaring and initializing Array 'array' with values
        String [] array = {"main"};

        //printing values of str and array[0]
        System.out.println("str : " + str + " , array[0] : " + array[0]);

        //calling function foo()
        foo(str, array);

        //printing values after calling function foo()
        System.out.println("str : " + str + " , array[0] : " + array[0]);
    }

    static void foo(String str, String[] array){
        str = "foo";
        array[0] = "foo";
    }

}

Output

str : main , array[0] : main  
str : main , array[0] : foo

Question

Why does the string str remains same as "main" but the value of array[0] gets modified from "main" to "foo" after calling the function foo()? Shouldn't the effect be the same?

Keiwan
  • 8,031
  • 5
  • 36
  • 49
  • 1
    The string literal cannot be changed by your method, as it's passed by value as a string literal, but the array can as the value passed for that array is its reference, so you can affect its contents via its reference. – ManoDestra Jun 10 '16 at 16:49
  • Strings in Java must be immutable – Peter Chaula Jun 10 '16 at 16:51
  • You can't modify a String because it's an immutable object. You're adviced to use a StringBuffer – kevin ternet Jun 10 '16 at 16:57

3 Answers3

1

That is because Arrays have headers that point to the object in memory. Arrays are really just references to other places. So when you modify the array you are modifying the element 0 which points to an object in memory. When your method exits you have not modified the array[0] reference and thus you are pointing to the same spot in memory in which you changed the object at.

The String on the other hand, when you assign it "foo" are really just changing it in the method scope, because you are changing the pointer to a new string. You would have to return the string or re-assign it to the reference in the main method or you could make the string a field in which it will always have the same reference.

This link might help explain it better then me.

Does Java pass by reference or pass by value?

Mr00Anderson
  • 854
  • 8
  • 16
1

No it shouldn't, because of how Java deals with references.

You give your method two parameters: a String (that is, the address to a String) and an array (that is, the address to an array). These addresses are stored locally in str and array, if you change the addresses, the addresses outside the method (str and array of main()) won't change.

Then you create a String "foo" and assign it (or rather, its adress) to local str. This won't have any effect on str of main(). However, the array address is local, but what's inside the array is not. So if you would write

array = {"foo"};

that wouldn't affect array of main(), but with

array[0] = "foo";

you change something inside the array you've given as a reference.

GreenThor
  • 456
  • 5
  • 14
1

In your code you passed str as an argument for foo. In java, when you pass any variable as an argument it becomes something new. Making changes to str in the foo method will only change that str and not main str.

However for array, both variables are grabbing from the same data. This happens because arrays are objects. When an object is passed by value it makes a copy, but objects which are copied still reference the same data.

It is better explained here: Java pass by reference or by value

Forseth11
  • 1,418
  • 1
  • 12
  • 21