5

I just read the following article on what passing by reference and passing by value means: http://qntm.org/call

So just to make sure I'm understanding correctly... Does that mean that calling by value in functions will NOT alter the original inputs, only a local copy of that input? However, since in Java and Python, the values are actually references to values, does that mean calling by value in functions WILL alter the original inputs?

2 Answers2

6

It depends what exactly you mean by input, specifically whether you mean a variable that appears as an argument at a call site, e.g., x in:

Object x = ...;
someMethod( x );

or you're talking about the actual object that the called function will see, e.g., the actual Object instance in:

someMethod( new Object() );

The value of variables (i.e., what object they refer to) won't change, but you can still do things to the objects that you get. E.g.,

void appendX( StringBuilder sb ) {
  sb.append('x');
}

void foo() {
  StringBuilder builder = ...
  appendX( builder );
  builder.toString(); // will contain 'x' because you worked with the object that 
                      // is the value of the variable `builder`.  When appendX was
                      // was invoked, the value of its variable `sb` was the same 
                      // object that is the value of foo's `builder`.  Without 
                      // changing what value the variable `builder` refers to, we
                      // did "change" the object (i.e., we appended 'x').
}

However, updating the reference in a method doesn't change any references outside of the method. From within a method, you can't, by assigning to one of the parameters of the method, change what object a variable outside the method refers to. E.g.:

void setNull( StringBuilder sb ) {
  sb = null;
}

void foo() {
  StringBuilder builder = ...
  appendX( builder );
  builder == null;  // false, because the value of the variable `builder` is still the 
                    // same object that it was before.  Setting variable `sb` in setNull
                    // to null doesn't affect the variable `builder`. The variables are
                    // just a name so that you can refer to an value.  The only way to
                    // what value a variable refers to is with an assignment.
}
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • I think this is the best way to explain this nuance. +1. – nook Sep 17 '13 at 18:34
  • @publ1c_stat1c It's an interesting nuance, because if you're working in a language (e.g., Java) where you can't modify the value of a variable by making a call to a method with the variable as an argument in the source (e.g., `someMethod( x )`), then it can be hard to imagine why any language would _let_ you do that. Yet in some languages, you can. :) – Joshua Taylor Sep 17 '13 at 18:36
1

In Java, there are a few basic types of variables: int, long, float, double and references. References are what you usually refer to as objects, for example a String. However, what is actually stored in the reference variable is not the object itself but rather an address to where the actual object is located in memory.

You never see this in Java, if you write String str = "hello", you think of str as the string "hello". But in fact, str contains a number - a memory address - to where the actual string "hello" is stored.

When you call a method in Java, its parameters are copied (passed by value). This is true even for objects like strings - except that the actual object isn't copied, just the reference. But, since the reference points to something (the actual objects location in memory) that is NOT copied you can use the reference to modify the actual object, even outside the function.

In C, you can actually pass by reference by using pointers:

void changeA(int* a) {
    *a = 5
} 
int main(void) {
    a = 10;
    changeA(&a); // pass by reference - &a means "address of a", similar to a reference in java
    printf("a: %d\n", a); // prints "5"
}
Johan Henriksson
  • 687
  • 3
  • 10