1

Ok, so I am a relatively new programmer. I have read over and over about passing variables. From what I have read here is what I've come to understand: In Java, when you pass a variable to a method (be it primitive or Object) you are ALWAYS passing by value. But what you are REALLY doing is passing a copy of the reference to an object or variable in memory.

So why do they call it pass by value? It seems to me you are passing by reference. Also, in C when you pass a pointer to a function, aren't you passing the address of a variable in memory? Yet it is called pass by value. What am I overlooking? Can someone please explain and clarify why I this? I know how to pass variables and such and I have read several SO posts on this but I am not fully satisfied yet. Consider an example:

  static void setNameStatic(Dog d, String name) {

        d.name = name;

  }


  public static void main (String args[]) {

           Dog d = new Dog("dog1");

           System.out.println( d.getName() );

           setNameStatic( d, "dog2" );

           System.out.println( d.getName() );

  }

Won't this output: dog1 and dog2. So aren't you going to where the reference is referring to and changing data around? What exactly does the value have to do with here? Any helpful comments are appreciated. And yes, I know it is pass by value, but why isn't it called "pass by sending copy of reference" lol?

Update: Thanks to everyone that gave a helpful answer. I know this was marked duplicate, and sorry about that. I am satisfied with the answers now.

Rob L
  • 3,073
  • 6
  • 31
  • 61

10 Answers10

4

Your memory looks like this at the moment of:

Dog d = new Dog("dog1");

Stack (with local vars)            Heap

+-----------+     points to
|  Dog d    | --------------->    real dog object
+-----------+
|  ...      |
+-----------+
|  ...      |
+-----------+

And then, when you pass in a reference to a method, it looks something like this (where the Dog dog2 is the method argument):

Stack (with local vars)            Heap
+-----------+
|  Dog d    | --------------->    real dog object
+-----------+                             ^
|  ...      |                             |
+-----------+                             |
|  Dog d2   |------------------------------
+-----------+

So, the reference is passed by value. It points to the same object but it is the new reference!

Meaning, if you would try something like this:

public static void main(String ... args) {
    Dog d= new Dog("dog1");
    setNameStatic(d, "dog2");
    System.out.println(d); // Still prints dog1 !!!
}

static void setNameStatic(Dog d2, String name) {
    d2= new Dog(name);
}

Because the new (copied) reference now points to the new object on heap and the original object has not changed.

darijan
  • 9,725
  • 25
  • 38
2

Because the value of any variable of reference type is its address in memory.

Because the value of any variable of primitive type is its value itself.

So you always pass values of variables.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
1

In java you're passing parameters by value to the methods, but the parameters are themselves ref type if the parameter is an object.

As a contrast in a programming language like C that passing by reference is allowed, if you print a reference you get something different from what you get when print it's value.

To insure that objects are reference types and compare them with primitives, Try this:

public class TestClass {
    public static void main(String[] args) {
        String s = new String("a");
        String t = new String("a");
        System.out.println(s==t);
        char a = 'a';
        char b = 'a';
        System.out.println(a==b);
    }
}

The result is :
false
true

Mohsen Kamrani
  • 7,177
  • 5
  • 42
  • 66
1

When you pass an object as a parameter in Java, you actually pass a reference, and the reference is the value used in the stack. However, any assignment you make to this reference inside the method will not be observed by the caller, because you only change a copy of the reference. Same goes with primitive values as parameters.

In other languages (like C++), you have the option to pass by reference, allowing you to change the reference itself from within a method. In Java, for example, you can't implement a swap method that takes two parameters and swaps them. In C++ it's possible.

Eyal Schneider
  • 22,166
  • 5
  • 47
  • 78
1

Every variable is passed by value. In the instance of primatives, we have the naive case - the values are passed into the function.

In the instance of Objects, we have a slightly more complicated although analogous paradigm - the references to the objects are passed by value.

Note the subtle differences:

//This is essentially a no-op. The values are only local to the function
void swap(int a, int b){
    int temp = a;
    a = b;
    b = temp;
}

//This is different. The references to a and b are passed by value so the values of a.x and b.x are actually swapped on return.
void swap(Point a, Point b){
    int temp = a.x;
    a.x = b.x;
    b.x = temp;
}
Sinkingpoint
  • 7,449
  • 2
  • 29
  • 45
1

Passing by value means that the value is transferred to method, i.e. yet another copy of the same value is created:

int i = 5; // one copy of 5
foo(i);

private void foo(int n) {
   // here n is 5, however it is "another" 5
}

The evidence of passing by value is that you cannot change your i from within the method foo():

int i = 5; // one copy of 5
foo(i);
// i is still 5 here

private void foo(int n) {
   n = 6;
   // n is 6, however it is actual inside the method only.
}

The same is with objects, however in that case reference is passed by value.

AlexR
  • 114,158
  • 16
  • 130
  • 208
1

Also, in C when you pass a pointer to a function, aren't you passing the address of a variable in memory? Yet it is called pass by value.

No it is not. When you pass a pointer to a value to a function in C, it is known as 'pass by reference'. The function can directly access & modify the original value because it has it's address. Pass by value is when you pass the value of objects instead of their locations or addresses. Look at the following examples.

int addOne(int x)
{
    return x + 1;
}

void destructiveAddOne(int *x)
{
  *x += 1;
}

int main(void)
{
    int x = 5;
    int y = 5;

    // We pass the _value_ of x, ie, 5 to addOne, and store the result in z.
    // The value of x will remain unchanged, ie, 5.
    int z = addOne(x);

    // We pass a REFERENCE to y, ie, it's address to destructiveAddOne()
    // destructiveAddOne then modifies the value of y to be y + 1. The value of y
    // has now CHANGED to 6. This is call by reference.
    destructiveAddOne(&y);

    return 0;
}
Prajjwal
  • 1,055
  • 2
  • 10
  • 17
1
  1. A variable holds the bits that tell the JVM how to get to the referenced Object in memory (Heap).

  2. When passing arguments to a method you ARE NOT passing the reference variable, but a copy of the bits in the reference variable. Something like this: 3bad086a. 3bad086a represents a way to get to the passed object.

  3. So you're just passing 3bad086a that it's the value of the reference.
  4. You're passing the value of the reference and not the reference itself (and not the object).
  5. This value is actually COPIED and given to the method.

Had that before: Is Java "pass-by-reference" or "pass-by-value"?

Community
  • 1
  • 1
1

It is a tricky thing to get your head round. I think of it as real numbers, albeit abstracted. Say your first dog, dog1, is created at memory location "100,000" (I know but bear with me). You pass the reference's value of 100,000 around to methods. Your method changes the name of the object living at 100,000.

If you pass your dog1 object into a method that does d = new Dog("dogXXX"), then it will work with a brand new object at (say) 200,000 leaving your dog1 at memory address 100,000 unchanged.

Apologies for the memory address abuse which will have experts spitting their coffee...

Brian
  • 6,391
  • 3
  • 33
  • 49
1

References in Java are passed by value of the reference. When you pass reference as a method parameter copy is created and you operate on this copy. To illustrate it have a look at this sample code:

final Person person = new Person();
person.setName("A");
changeName(person, "B");
System.out.println(person.getName());

Now if we have changeName implemented as this:

private static void changeName(Person person, String name) {
    person.setName(name);
}

Then the result is B. It's because copy of the reference still points to the same object and there is possibility to modify it.

On the other hand if you change the changeName method to this:

private static void changeName(Person person, String name) {
    person = new Person();
    person.setName(name);
}

Then the result is A. It's because copy of the reference points to the new object, but original reference still points to the original object and it's value is not modified. If Java would pass object references by reference than the result would be B, because it would operate on the original object.

Jakub H
  • 2,130
  • 9
  • 16