3
public class Test {

    public static void change(char[] a){
        a[0] = '1';
        a[1] = '2';
    }

    public static void main(String args[]){
        char[] a = new char[]{'a','b'};

        change(a);

        System.out.println(a);
    }

}

The output is 12

public class Test {

    public static void change(char[] a){
        a = new char[]{'1','2'};
    }

    public static void main(String args[]){
        char[] a = new char[]{'a','b'};

        change(a);

        System.out.println(a);
    }

}

The output is ab. I understand I am missing something about the way java passes method arguments. I understand references to objects are passed by value. However, I cannot reconcile what I understand with the results of these programs.

user2056257
  • 141
  • 6
  • 2
    Java is [pass by value](http://stackoverflow.com/questions/40480/is-java-pass-by-reference), not by reference. – Pshemo Feb 09 '13 at 01:35

6 Answers6

8

In version "2", the change method "does nothing", because you are assigning a new array to a, which is the the local (parameter) variable a. This has no effect on the array assigned to variable a declared in the main method.

The new array goes out of scope and is inaccessible (and thus earmarked for garbage collection) when the change() method completes.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 1
    For this reason you should consider it a bad practice to re-assign parameters unless it ends up making the code look cleaner. – Daniel Kaplan Feb 09 '13 at 01:51
4

This is because Java passes by value, not by reference. In the case of references, you copy the reference. You can modify the values behind the reference (version 1), but not the reference itself (version 2).

Oleksi
  • 12,947
  • 4
  • 56
  • 80
2

With the call to

a = new char[]{'1','2'};

all that happens is that the variable a local to the method is assigned a new reference, this does not have any effect on the variable a in your main method which still references the old array.

Peter Karlsson
  • 1,170
  • 7
  • 15
1

first one, you are changing the array that gets passed in and is referenced by 'a'

second one, you are changing what array that is referenced by 'a'

effectively, the second one you are doing

char[] original = new char[]{'a','b'};
// this is basically what your function call is doing from here....
char[] a = original;      // a is now also referencing the ab array
a = new char[]{'1','2'};  // now a is referencing a 1 2 array.
// then the function returns....and original is the same still

so a is referencing a new array, while the original is referencing the original array still

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
1

This is happening because of the way you are passing the data. In the first example the array is changed because you are passing the Change() method the address of the array and the method is changing the data in the address.

In the second example the array IS passed however you are initializing a new array which is declaring new memory space and changing the address that was passed in. This however, doesn't delete the original declared and initialized instance of char[] in the main method so when you print it out it prints out the local char[] and not the new one you tried to create.

DotNetRussell
  • 9,716
  • 10
  • 56
  • 111
1

Because Java passes objects between methods by value and not by reference. In the 1st example, you instantiate an object in the main and pass it to change, which only alters it by setting values. In the 2nd example, you actually reinstantiate it in change (using new) after you instantiated it once already in the main. The scope of the reinstantiated char[] in change will be the method only so when you go back to main that called it, it will revert to its own instance, not the one one used locally by change

amphibient
  • 29,770
  • 54
  • 146
  • 240