Is Java really passing objects by value?

32,256

Solution 1

Java always passes arguments by value, NOT by reference. In your example, you are still passing obj by its value, not the reference itself. Inside your method changeName, you are assigning another (local) reference, obj, to the same object you passed it as an argument. Once you modify that reference, you are modifying the original reference, obj, which is passed as an argument.


EDIT:

Let me explain this through an example:

public class Main
{
     public static void main(String[] args)
     {
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will change the object that the reference refers to!
     }
     public static void changeReference(Foo a)
     {
          Foo b = new Foo("b");
          a = b;
     }
     public static void modifyReference(Foo c)
     {
          c.setAttribute("c");
     }
}

I will explain this in steps:

1- Declaring a reference named f of type Foo and assign it to a new object of type Foo with an attribute "f".

Foo f = new Foo("f");

Enter image description here

2- From the method side, a reference of type Foo with a name a is declared and it's initially assigned to null.

public static void changeReference(Foo a)

Enter image description here

3- As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.

changeReference(f);

Enter image description here

4- Declaring a reference named b of type Foo and assign it to a new object of type Foo with an attribute "b".

Foo b = new Foo("b");

Enter image description here

5- a = b is re-assigning the reference a NOT f to the object whose its attribute is "b".

Enter image description here


6- As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute "f".

Enter image description here

7- c.setAttribute("c"); will change the attribute of the object that reference c points to it, and it's same object that reference f points to it.

Enter image description here

I hope you understand now how passing objects as arguments works in Java :)

Solution 2

In Java, an object handle, or the identity of an object is considered a value. Passing by value means passing this handle, not a full copy of the object.

A "reference" in the term "pass by reference" also doesn't mean "reference to an object". It means "reference to a variable" – a named "bucket" in a function definition (or, rather, a call frame) that can store a value.

Passing by reference would mean the called method could change variable values in the calling method. (For example, in the C standard library, the function scanf works this way.) This isn't possible in Java. You can always change the properties of an object – they aren't considered a part of its "value". They're completely different independent objects.

Solution 3

It did not change obj (your code doesn't change it anyway). Had it been passed by reference, you could have written:

public static void changeName(myObject obj){
    obj = new myObject("anotherName");
}

And have "anotherName" printed by the main method.

Solution 4

You're changing a property of obj, not changing obj (the parameter) itself.

The point is that if you pointed obj at something else in changeName that that change would not be reflected in main.

See this post for further clarification.

Solution 5

It is passing the reference to obj as a value (a bit confusing I know :)).

So let's say it makes a copy of the pointer to obj's value and pass that.

That means that you can do things like:

  public static void changeName(myObject obj){    
        obj.setName("anotherName");
        obj = new myObject();
    }

and the statement

System.out.print(obj.getName());

is still going to refer to the old object (the one that you did setName).

Share:
32,256
MBZ
Author by

MBZ

Updated on July 09, 2022

Comments

  • MBZ
    MBZ almost 2 years

    Possible Duplicate: Is Java pass by reference?

    public class myClass{
        public static void main(String[] args){
            myObject obj = new myObject("myName");
            changeName(obj);
            System.out.print(obj.getName()); // This prints "anotherName"
        }
        public static void changeName(myObject obj){
            obj.setName("anotherName");
        }
    }
    

    I know that Java pass by value, but why does it pass obj by reference in previous example and change it?

    • G_H
      G_H over 12 years
      This has been asked, like, a million times.
    • Sam Ginrich
      Sam Ginrich about 2 years
      Your example illustrates a logic of what long time before Java was called "call be reference" or "object passed be reference". Now when it comes to Java, there is a congregation on an island with dogma "Java is pass by value" and according to this dogma they will twist the entire world to make this true, not to begin with "Java is pass by value" is a grammatical nonsense. According to the dogma e.g. an object is not a value, but a reference of an object is.
  • MBZ
    MBZ over 12 years
    thanks you alot, for explaining in details.
  • Jemshit Iskenderov
    Jemshit Iskenderov about 9 years
    Now i got what "reference to obj as a value" or "sending copy of reference" means :)
  • Laszlo Varga
    Laszlo Varga over 8 years
    Just a small remark: myObject should be MyObject.
  • VIN
    VIN about 8 years
    The diagrams really helped make these concepts clear! Thank you!
  • Tom Auger
    Tom Auger over 7 years
    I appreciated this answer as it explained that in Java an object property isn't considered part of its "value". But in my world, allowing a function or method with its own scope to modify a variable (or an object) that's outside its scope and in the calling method's scope is "pass by reference", sorry Java guys.
  • Montre
    Montre over 7 years
    So what's your point? Different languages have different conceptual models, and different terminologies. As long as "your world" is not the Java world, or that of one of Java's relatives, it's not really relevant here, is it? I could just as well argue that PHP and Perl are the odd ones out by natively implementing "pass-by-deep-copy", but that's just semantics and not useful to anybody. Java's terminology is roughly consistent with how C works - the difference between passing foo or &foo.
  • Montre
    Montre over 7 years
    And in C++, another ancestor of Java, passing by reference as opposed to value again has no relation to whether a function is changing state not directly in the stack frame. That's what const is for. (Although given C++'s extraordinary flexibility, it's certainly possible for passing by value to copy an object however you wish.) In these languages, a reference more or less means a (local) variable that you can assign a value to and change state outside the current scope. Not merely any variable pointing to possibly non-local state.
  • Montre
    Montre over 7 years
    It's really mostly about the level at which you think about things, and what you think is the "value" of a variable. At a low level, a Java variable is the name for the address of a tiny chunk of memory that contains, say, 8 bytes of data. (Java does not do stack-allocation of data structures, I don't think older versions of C did either, and PHP probably doesn't either.) This memory either contains a datum directly if it's a simple data type or an integer, or it contains another memory address of a bigger chunk of memory. When we talk about the value of the variable, we mean those 8 bytes.
  • Tom Auger
    Tom Auger over 7 years
    thanks for the additional clarification, maybe minus the attitude. The other parts were helpful.
  • gurubelli
    gurubelli over 7 years
    very nice explanation
  • Hiroki
    Hiroki over 6 years
    This explanation is very clear, but I'm still a bit confused. In the step 3, "a" is pointing to an object whose attribute is f. To me, "a" seems to be pointing the reference of the object which "f" is pointing too. If objects are passed by values, both "a" and "f" should have their own objects. However, they are actually sharing the same objects (i.e. they are pointing to the reference of the same object).
  • fishinear
    fishinear about 4 years
    @Hiroki Objects are not passed by value. It is the pointer to the object that is passed by value. Variables in Java cannot contain objects, they always contain a pointer to the object. And therefore, objects cannot be passed to methods, it is always the pointer to the object that is passed by value to the method.
  • Sam Ginrich
    Sam Ginrich about 2 years
    There is nothing like "reference to a variable" unless "variable" is precisely an object.
  • Sam Ginrich
    Sam Ginrich about 2 years
    You didn't answer the question: objects themselves are never on the stack in Java.
  • Sam Ginrich
    Sam Ginrich about 2 years
    Have not seen a definition of "reference" in contrast to "reference as value" and thus it remains unclear by what means an object is passed, 'cause the actual use case is ´passing an object to some method´, where the object is shared between caller and called method, where the reference appears as technical aspect, not really touching the semantics of a shared object.