0

When I run this code, it prints 0 , 1, 2, but I have no idea why. could you explain me?

public void run() {
        int[] arr =  new int [3];
        for(int i=0; i<arr.length;i++){
            arr[i]=i;
        }
        domore(arr);
        for(int i=0; i<arr.length;i++){
            println(arr[i]);
        }
    }

    private void domore(int[] arr) {
        // TODO Auto-generated method stub
        int [] att = new int [3];
        for(int i=0; i<att.length;i++){
            att[i]=77;
        }
        arr=att;
    }
  • With `arr=att;` you're only reassigning the local copy of the reference to the array. Google pass-by-value vs. pass-by-reference. – blgt Jan 23 '14 at 10:22

8 Answers8

8

In Java - "References to objects are passed by Value". Any change you make in the doMore() method will not be reflected in your original array because you are reassigning the passed reference there... ( Please use camelCase for naming methods/fields. i.e, use doMore() instead of domore).

public void run() {
        int[] arr =  new int [3];   // arr points to an integer array of size 3
         doMore(arr);
        } 
 private static void doMore(int[] arrNew) {   // arrNew is copy of arr so it  also points to the same integer array of size 3. So, any changes made by arrNew are as good as changes made by arr (and yes data of arr is changed..)        
        // TODO Auto-generated method stub
        int [] arrNew = new int [3];           // you are making arrNew point to new integer array of size 3. So, now arrNew points to a new object and not to the one pointed by arr. 
        for(int i=0; i<arrNew.length;i++){
            arrNew[i]=77;
        }

    }
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • but if I write in "doMore" method arr[1]=33; it will be changed ! – user3151874 Jan 23 '14 at 10:27
  • @user3151874 That is because a copy of the reference is passed. Which means changes to an object passed as an argument will effect the initial reference. However assigning a new reference to that reference will not affect the reference passed into the method. See: http://www.javaranch.com/campfire/StoryPassBy.jsp – Kevin Bowersox Jan 23 '14 at 10:33
3

In the method domore int[] arr is passed as an argument, meaning a copy of the reference is passed (aka by value). In the method a new int[] is created and then assigned to the copy of the reference (int[] arr). This will never change the initial int[] created in the run method. It will only assign the passed argument to the newly created array within domore().

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
1

Because you are putting a reference of your arr-Array to the method domore. Inside it you are cutting this reference by setting arr=att. The outer method run is not able to recognize this newly set reference and will stay with your old array reference where you have put the values 0, 1, 2.

bobbel
  • 3,327
  • 2
  • 26
  • 43
1

Try returning the array arr in domode method

public void run() {
    int[] arr =  new int [3];
    for(int i=0; i<arr.length;i++){
        arr[i]=i;
    }
    arr = domore(arr);
    for(int i=0; i<arr.length;i++){
        println(arr[i]);
    }
}

private int[] domore(int[] arr) {
    // TODO Auto-generated method stub
    int [] att = new int [3];
    for(int i=0; i<att.length;i++){
        att[i]=77;
    }
    return(att);
}
0

domore is a void function. If you wan't your Values to change you'll have to return something.

private int[] domore (int[] arr){
int [] att = new int [3];
    for(int i=0; i<att.length;i++){
        att[i]=77;
    }
    return att;
}

And you call it by:

arr = domore(arr);
Lucas
  • 33
  • 9
  • You only have to set the values in the method parameter `arr`. Because the outer method has this reference to it! – bobbel Jan 23 '14 at 10:25
0

You are working with an array of primitives. If you change int to Integer (from primitives to objects) you should not have that problem.

int a=5;
int b=a;
b=10;

->a will still be 5. if you want to use primitives, then just return the int array and assign it to the initial array

arr=doMore(arr);
diazazar
  • 522
  • 1
  • 5
  • 24
0

When you are passing any parameter value in function, scope of that will be local to that function only.

And another thing is, In java you are calling a function by value not by reference.

If you want to use modified value, you have to return that from function.

public void run() {
            int[] arr =  new int [3];
            for(int i=0; i<arr.length;i++){
                arr[i]=i;
            }
            // arr is in run() method
            domore(arr);
            for(int i=0; i<arr.length;i++){
                System.out.println(arr[i]);
            }
        }

        private void domore(int[] arr) {
            // TODO Auto-generated method stub
            int [] att = new int [3];
            for(int i=0; i<att.length;i++){
                att[i]=77;
            }
            arr=att; // here scope of arr is local for domore() method only
            // so arr in run() method will not modified.
        }
Not a bug
  • 4,286
  • 2
  • 40
  • 80
-1

use arr = (int[]) att.clone(); or you can use Array.copyOf method too!!!

instead of arr=att

VijayD
  • 826
  • 1
  • 11
  • 33
  • This does not solve the problem, because the reference will still hold the array with the elements `0, 1, 2`! – bobbel Jan 23 '14 at 10:36
  • @bobble... i thought he wanted to change the content of the array. – VijayD Jan 23 '14 at 11:52
  • That's true! But... If you clone the array in the `domore` method, it's no advantage to this problem. In the `run` method the `arr` variable will still hold a reference to the array which contains `0, 1, 2`. – bobbel Jan 23 '14 at 12:02