0

One of the most popular answers to one of the most popular questions in Java here reads:

Java is always pass-by-value. The difficult thing to understand is that Java passes objects as references and those references are passed by value.

So what does "Java passes objects as references and those references are passed by value." mean?

Does it mean that:

The memory location to which the original variable points is copied as the value of the new temporary variable? (if this is the case, all the changes made inside the function will be reflected in the original, right?)

If not, what does it mean?

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
Trent Boult
  • 117
  • 3
  • 2
    how is this not a duplicate of [Is Java “pass-by-reference” or “pass-by-value”](http://stackoverflow.com/q/40480/217324) ? – Nathan Hughes Mar 09 '15 at 03:20
  • no, it's the reference to that memory location that gets copied. This way, changes to the argument's fields will be propagated to the original object but a re-assignment of the field to a new object will not change the existing object. – Jeroen Vannevel Mar 09 '15 at 03:21
  • You're essentially correct: the identity of the object is copied and a copy of that identity is passed. There's no actual requirement that the identity of an object has to be represented by its memory location, but a JVM implementation that does that will always work. Note that primitive types are not objects, and behave differently. – James_D Mar 09 '15 at 03:24

4 Answers4

2

Think of objects references as "pointers to a value"

When you pass a value into a method, you pass the pointer in, therefore the two pointers (the one in the method, and the one you passed in) point to the same thing.

Consider this

public static void main(String[] args){
    Foo cl = new Foo();
    cl.z= 100;
    method(cl);
    System.out.println(cl.z);

}

private static void method(Foo bar){
    bar.z=10;
}

Before you call method, cl.z would be 100, but after you pass it in, it would be equal to 10.

What is not correct is this:

public static void main(String[] args){
    Foo cl = new Foo();
    cl.z= 100;
    method(cl);
    System.out.println(cl.z);

}

private static void method(Foo bar){
    bar = new Foo();
    bar.z=10000;
}

This would NOT print out 10000, because you cannot assign the pointer to reference a different object

EDToaster
  • 3,160
  • 3
  • 16
  • 25
0

Yes, Java is always pass-by-value, with both reference types and primitive types. But that doesn't mean that changes within functions always affect the object passed in as an argument.

If a primitive type is passed in, then there is no reference passed, it's by pure value, and any values in the calling scope will not change.

If a reference type is passed in, whether or not a function can modify it depends upon if the type is mutable (the object can be modified) or immutable (the object itself cannot be modified, a new object must be created for all modifications).

If it is mutable, like StringBuilder or HashMap<String, String>, then the function is able to modify it and changes within the function will still be in place after the function call returns. However, note that changing what a reference type points to is not modifying it, in that case, you are only changing what the reference type points to, not the original object referenced by an argument, but doing an operation like strbuilder.append("xyz") is.

If it is immutable, like String or Integer then all modifications within the function will create a new object and the changes will not be in place after the function call returns.

Shashank
  • 13,713
  • 5
  • 37
  • 63
0

When we say Java is pass-by-value, it means that if you modify a parameter inside a method, it has no effect on the caller. For example:

public void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

All this does is swap local copies of the parameters. Thus, if you say

int x = something;
int y = somethingElse;
swap(x, y);

x and y would not change.

The same is true for references:

public void someOperation(MyClass a) {
    a = ...something...;
}

Inside your method, a is a copy of whatever reference you pass in; if you reassign a to something else in the method, it doesn't affect any variable in the caller.

MyClass x = ...;
someOperation(x);

x does not change, even though you've changed the parameter a inside the method.

Note that this means that x itself will not change. It will not point to a different MyClass instance, even though a in the method was changed to refer to a different MyClass instance. However, even though the reference does not changed, the object that the reference refers to could be changed by the method.

ajb
  • 31,309
  • 3
  • 58
  • 84
0

It means the reference (a memory pointer to the object) is passed by value. If you modify the object, you modify the reference to the object; thus the change will be seen across your application. If you modify the pointer, then your only change it for the scope of your method.

void method(Foo f) {
    f.bar = 10; // Seen accross your application.
    f = new Foo(); // Modifying your pointer. This does not change the previous object.
}
Jazzwave06
  • 1,883
  • 1
  • 11
  • 19