0

This is in java. I tried looking for / googling for an answer to this question here and couldn't find a sufficient answer, so I apologize if this is a duplicate. I am confused as to the rules behind methods changing the parameter that you input. For example, consider the following example

public static void messWithArray(int[] array)
{
     array[0] = 100;
     array[0] += 5;

     // make new array
     int[] array2 = new int[10];
     for(int i = 0; i < 10; i++)
     {
         array2[i] = 5+i;
     }
     array = array2
 }
 public static void main(String[] args)
 {
     int[] a = new int[10]
     for(int i=0; i < 10; i++)
     {
         a[i] = i*10
     }
     messWithArray(a);
     System.out.println(a[0]);
     System.out.println(a[1]);

This prints that a[0] is 105 and a[1] is 10, so making array[0] equal to 100 and adding 5 to it in the messWithArray method had an effect. However, assigning array = array2 didn't do anything (since a[1] is 10). I also tried messing with an int but couldn't get it to work.

I would like to know more specifically/clearly the logic behind whether or not a method will change attributes of an array.

walther
  • 13,466
  • 5
  • 41
  • 67
MT_
  • 535
  • 1
  • 8
  • 20
  • This is Java, right? – KSFT Feb 28 '15 at 02:07
  • @KSFT Yes, that completely passed my mind. – MT_ Feb 28 '15 at 02:09
  • This is mostly just a guess based on how it works in other languages, but I'm pretty sure objects can be modified (for example, assigning values to array indices), but types like ints or chars can't be. `array = array2;` is just changing what the name `array` refers to, so it doesn't change the value of a variable. Again, this might be totally wrong. – KSFT Feb 28 '15 at 02:13
  • 2
    see http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value – Andreas Feb 28 '15 at 02:13
  • @Andreas that one came up in my googling but I'm honestly still a bit confused after reading it :/ I don't know how to apply what I learned frmo that question to the example above – MT_ Feb 28 '15 at 02:17
  • To elaborate on the answer referred to by @Andreas -- your array is a kind of object in Java. You pass the reference to that array to the method, which can then change its *contents*. It cannot change the reference that the caller holds, in other words, it cannot change the array that the caller refers to by assigning another value to it. This is what is meant by "passing the reference to an object by value" -- the reference is passed by value, allowing the method to change the object's (or the array's) contents. – arcy Feb 28 '15 at 02:17
  • @arcy A*ha*! I was right (I think)! – KSFT Feb 28 '15 at 02:18
  • @arcy so I visualize the array as a circle with elements. the variable array is pointing to that. when I change the elements of the array, the variable array is still pointing to that circle, so since the physical array gets changed so does the variable array. however, when I assign array = array2, i am creating a new instance of the variable array, so that has no effect on the original variable array pointing to the circle of elements? – MT_ Feb 28 '15 at 02:23
  • 2
    @Soke that is correct; let us say your circle of elements resided at memory location 12345. When the caller called the method, it passed 12345 as the address of the array, and the called method therefore got a memory location that held 12345 as a value. Using that as a reference to the elements, the called method can change the elements. But it has no way of knowing in what location the caller held 12345, and there is no statement the called method can make that will change the caller's memory location to point to something else. – arcy Feb 28 '15 at 02:27

3 Answers3

4

In Java, method parameters are always passed by value. However, all objects (which includes arrays, even arrays of primitives) are referred to by a pointer, which allows modification of the object through its methods (or via array access for arrays), and it's the pointer that's passed by value.

You can never re-seat what the parameter referred to in the caller, but you can always mutate something mutable.

public void someMethod(int param1, List<String> param2, double[] param3) {
  // In here, I can change what 'param1', 'param2', or 'param3' refer to:
  param1 = 3;
  // but this didn't change the value from whoever called me.
  // Doing "param2 = new ArrayList<>();" similarly wouldn't affect the caller.
  // The pointer to the list was simply copied.
  param2.add("Hello");
  // However, that ^ modified the list through the pointer.
  // Same is true for arrays:
  param3[0] = 0.0; // modified the original array
  param3 = new double[3]; // changed 'param3' to refer to a new array
}
MattPutnam
  • 2,927
  • 2
  • 17
  • 23
  • "...and it's the pointer that's passed by value," and that's indeed why in Java all objects are *passed by reference*, i.e. not copied, and all primitives *by value*. – theV0ID Feb 28 '15 at 02:23
  • @theV0ID: Nope. "Objects" are not values in Java (there are no "object types") and thus cannot be "passed". – newacct Mar 01 '15 at 23:51
1

I can explain it to you from memory point of view. array is like a pointer pointing to a specific block of memory (let say a memory address as a Long value). When you pass it to memory you pass this pointer to the function. array[5] is like that point + 5 meaning the fifth cell o memory after where array shows. When you do array[5]=100 you actually change the value of a cell of memory which points the fifth cell after where array shows. so you actually change a value inside array. but array2 is a pointer to another cell of the memory. So when you do array = array2 you just change the pointer to new location. So since the pointer is copied via method call, the original pointer outside the function keeps the same and you still see the elements of array

Nami
  • 1,215
  • 11
  • 21
0
class Arrays
{
public static void messWithArray(int[] array)
{
     array[0] = 100;
     array[0] += 5;

     // make new array
     int[] array2 = new int[10];
     for(int i = 0; i < 10; i++)
     {
         array2[i] = 5+i;
    System.out.println(array2[i]);
     }
     array = array2;
System.out.println("CHANGED VALUE --->"+array[0]);
 }
 public static void main(String[] args)
 {
     int[] a = new int[10];
     for(int i=0; i < 10; i++)
     {
         a[i] = i*10;
     }
     messWithArray(a);
     System.out.println(a[0]);
     System.out.println(a[1]);
 }
}

You should return the updated array from your messWithArray() function, this would update the array values.

  • Yeah, I know. The messWithArray() function wasn't actually trying to accomplish anything, I was just testing the way that parameter passing works – MT_ Feb 28 '15 at 07:57