Pass-by-value

  • The actual parameter (or argument expression) is fully evaluated and the resulting value is copied into a location being used to hold the formal parameter’s value during method/function execution.
  • That location is typically a chunk of memory on the runtime stack for the application (which is how Java handles it), but other languages could choose parameter storage differently.

Pass-by-reference

  • The formal parameter merely acts as an alias for the actual parameter. Anytime the method/function uses the formal parameter (for reading or writing), it is actually using the actual parameter.
  • Java passes everything by value, and not by reference – make sure you remember that. And when we say everything, we mean everything – objects, arrays (which are objects in Java), primitive types (like ints and floats), etc. – these are all passed by value in Java.

Java is always pass-by-value. Unfortunately, they decided to call pointers references, thus confusing beginners. Because those references are passed by value. For Example,

[pastacode lang=”java” manual=”public%20static%20void%20main(%20String%5B%5D%20args%20)%7B%0A%20%20%20%20Dog%20aDog%20%3D%20new%20Dog(%22Max%22)%3B%0A%20%20%20%20foo(aDog)%3B%0A%0A%20%20%20%20if%20(aDog.getName().equals(%22Max%22))%20%7B%20%2F%2Ftrue%0A%20%20%20%20%20%20%20%20System.out.println(%20%22Java%20passes%20by%20value.%22%20)%3B%0A%0A%20%20%20%20%7D%20else%20if%20(aDog.getName().equals(%22Fifi%22))%20%7B%0A%20%20%20%20%20%20%20%20System.out.println(%20%22Java%20passes%20by%20reference.%22%20)%3B%0A%20%20%20%20%7D%0A%7D%0Apublic%20static%20void%20foo(Dog%20d)%20%7B%0A%20%20%20%20d.getName().equals(%22Max%22)%3B%20%2F%2F%20true%0A%0A%20%20%20%20d%20%3D%20new%20Dog(%22Fifi%22)%3B%0A%20%20%20%20d.getName().equals(%22Fifi%22)%3B%20%2F%2F%20true%0A%7D” message=”Java Code” highlight=”” provider=”manual”/] [ad type=”banner”]

In this example aDog.getName() will still return “Max”. The value aDog within main is not overwritten in the function foo with the Dog “Fifi” as the object reference is passed by value. If it were passed by reference, then the aDog.getName() in main would return “Fifi” after the call to foo.

Likewise:

[pastacode lang=”java” manual=”Dog%20aDog%20%3D%20new%20Dog(%22Max%22)%3B%20%0Afoo(aDog)%3B%20%0AaDog.getName().equals(%22Fifi%22)%3B%20%2F%2F%20true%20%0Apublic%20void%20foo(Dog%20d)%20%0A%7B%20%0Ad.getName().equals(%22Max%22)%3B%20%2F%2F%20true%0A%20d.setName(%22Fifi%22)%3B%20%0A%7D%20″ message=”Java Code” highlight=”” provider=”manual”/]

In this example, FiFi is the dog’s name after call to foo(aDog). Any operations that foo performs on d are such that, for all practical purposes, they are performed on aDog itself (except d=new Dog(“Boxer”)).

Another Example that clearly defines java always pass-by-value and not by reference

[pastacode lang=”java” manual=”public%20class%20Main%7B%0A%20%20%20%20%20public%20static%20void%20main(String%5B%5D%20args)%7B%0A%20%20%20%20%20%20%20%20%20%20Foo%20f%20%3D%20new%20Foo(%22f%22)%3B%0A%20%20%20%20%20%20%20%20%20%20changeReference(f)%3B%20%2F%2F%20It%20won’t%20change%20the%20reference!%0A%20%20%20%20%20%20%20%20%20%20modifyReference(f)%3B%20%2F%2F%20It%20will%20modify%20the%20object%20that%20the%20reference%20variable%20%22f%22%20refers%20to!%0A%20%20%20%20%20%7D%0A%20%20%20%20%20public%20static%20void%20changeReference(Foo%20a)%7B%0A%20%20%20%20%20%20%20%20%20%20Foo%20b%20%3D%20new%20Foo(%22b%22)%3B%0A%20%20%20%20%20%20%20%20%20%20a%20%3D%20b%3B%0A%20%20%20%20%20%7D%0A%20%20%20%20%20public%20static%20void%20modifyReference(Foo%20c)%7B%0A%20%20%20%20%20%20%20%20%20%20c.setAttribute(%22c%22)%3B%0A%20%20%20%20%20%7D%0A%7D” message=”Java Code” highlight=”” provider=”manual”/]
  • 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”);
  • 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)
  • As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.
    changeReference(f);
  • 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”);
  • a = b is re-assigning the reference a NOT f to the object whose its attribute is “b“
  • As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute “f”.
  • 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.
  • Thus this is represented diagrammatically,

 

Java does manipulate objects by reference, and all object variables are references. However, Java doesn’t pass method arguments by reference; it passes them by value.

Take the badSwap() method for example:

[pastacode lang=”java” manual=”public%20void%20badSwap(int%20var1%2C%20int%20var2)%0A%7B%0A%20%20int%20temp%20%3D%20var1%3B%0A%20%20var1%20%3D%20var2%3B%0A%20%20var2%20%3D%20temp%3B%0A%7D” message=”Java Code” highlight=”” provider=”manual”/]
  • When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object, since Java passes object references by value as well. Now, here is where it gets tricky:
[pastacode lang=”java” manual=”public%20void%20tricky(Point%20arg1%2C%20Point%20arg2)%0A%7B%0A%20%20arg1.x%20%3D%20100%3B%0A%20%20arg1.y%20%3D%20100%3B%0A%20%20Point%20temp%20%3D%20arg1%3B%0A%20%20arg1%20%3D%20arg2%3B%0A%20%20arg2%20%3D%20temp%3B%0A%7D%0Apublic%20static%20void%20main(String%20%5B%5D%20args)%0A%7B%0A%20%20Point%20pnt1%20%3D%20new%20Point(0%2C0)%3B%0A%20%20Point%20pnt2%20%3D%20new%20Point(0%2C0)%3B%0A%20%20System.out.println(%22X%3A%20%22%20%2B%20pnt1.x%20%2B%20%22%20Y%3A%20%22%20%2Bpnt1.y)%3B%20%0A%20%20System.out.println(%22X%3A%20%22%20%2B%20pnt2.x%20%2B%20%22%20Y%3A%20%22%20%2Bpnt2.y)%3B%0A%20%20System.out.println(%22%20%22)%3B%0A%20%20tricky(pnt1%2Cpnt2)%3B%0A%20%20System.out.println(%22X%3A%20%22%20%2B%20pnt1.x%20%2B%20%22%20Y%3A%22%20%2B%20pnt1.y)%3B%20%0A%20%20System.out.println(%22X%3A%20%22%20%2B%20pnt2.x%20%2B%20%22%20Y%3A%20%22%20%2Bpnt2.y)%3B%20%20%0A%7D” message=”Java Code” highlight=”” provider=”manual”/] [ad type=”banner”]

output:

X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0

  • The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In the main() method, pnt1 and pnt2 are nothing more than object references.
  • When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references.
  • Figure 1 below shows two references pointing to the same object after Java passes an object to a method. This diagram shows After being passed to a method, an object will have at least two references

  • Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects.
  • But since the references are copies, swaps will fail. As Figure 2 illustrates, the method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references.
  • For a swap to succeed outside of the method call, we need to swap the original references, not the copies.

  • “Java manipulates objects ‘by reference,’ but it passes object references to methods ‘by value.'” As a result, you cannot write a standard swap method to swap objects.
  • Example of pass by value in Java

Suppose we have a method that is named “Receiving” and it expects an integer to be passed to it:

[pastacode lang=”java” manual=”public%20void%20Receiving%20(int%20var)%0A%7B%0A%20%20var%20%3D%20var%20%2B%202%3B%0A%7D%0ANote%20that%20the%20%E2%80%9Cvar%E2%80%9D%20variable%20has%202%20added%20to%20it.%20Now%2C%20suppose%20that%20we%20have%20some%20code%20which%20calls%20the%20method%20Receiving%3A%0A%0Apublic%20static%20void%20main(String%20%5B%5D%20args)%0A%7B%0A%20%20int%20passing%20%3D%203%3B%0A%0A%20%20Receiving%20(passing)%3B%0A%20%0A%20%20System.out.println(%22The%20value%20of%20passing%20is%3A%20%22%20%2B%20passing)%3B%0A%7D” message=”Java Code” highlight=”” provider=”manual”/]
  • In the main method, we set the variable “passing” to 3, and then pass that variable to the Receiving method, which then adds 2 to the variable passed in.
  • What do you think the “System.out.println” call will print out? Well, if you thought it would print out a “5” you are wrong. It will actually print out a “3”. Why does it print out a 3 when we clearly added a 2 to the value in the Receiving method?
  • The reason it prints out a “3” is because Java passes arguments by value – which means that when the call to “Receiving” is made, Java will just create a copy of the “passing” variable and that copy is what gets passed to the Receiving method – and not the original variable stored in the “main” method.
  • This is why whatever happens to “var” inside the Receiving method does not affect the “passing” variable inside the main method.

How does pass by value work?

  • Java basically creates another integer variable with the value of 3, and passes that to the “Receiving” method. That is why it is called “pass by value” – because the value of 3 is what is being passed to the “Receiving” method, not a reference to the “passing” variable.

Are objects passed by reference in Java?

  • Objects are not passed by reference in Java. Let’s be a little bit more specific by what we mean here: objects are passed by reference – meaning that a reference/memory address is passed when an object is assigned to another – BUT (and this is what’s important) that reference is actually passed by value.
  • The reference is passed by value because a copy of the reference value is created and passed into the other object – read this entire article and this will make a lot more sense. So objects are still passed by value in Java, just like everything else.
  • One other very important thing to know is that a variable of a class type stores an address of the object, and not the object itself. The object itself is stored at the address which the variable points to. Let’s suppose we have a class called SomeClass and that we instantiate it with a variable of the SomeClass type.

So, suppose we have the following very simple code:

SomeClass someVar;

  • The someVar variable above is a variable of a class type – which is commonly referred to as an object. But, what actually happens behind the scenes is that someVar will just contain a reference – which is basically a memory address that points to the real object and all the class variables for that object actually lives. So, remember that a variable of a class type – or what is commonly referred to as an object of a class – really just stores a memory address that points to the real object. Bottom line: anytime you see a variable of a class type like the someVar variable above, just remember that it is basically a reference that stores an address in memory.
  • An example and some diagrams will help make this very clear. Suppose we have a class called PersonClass, which has a method called set that just sets the name and age for a given Person object. The details of the class itself don’t matter for the purpose of this example so we won’t bother to show the implementation of PersonClass.

Now, let’s say we have the following code:

[pastacode lang=”java” manual=”%2F%2Fcreate%20an%20object%20by%20passing%20in%20a%20name%20and%20age%3A%0APersonClass%20variable1%20%3D%20new%20PersonClass(%22Mary%22%2C%2032)%3B%0A%0APersonClass%20variable2%3B%0A%0A%2F%2F%20Both%20variable2%20and%20variable1%20now%20both%20name%20the%20same%20object%0Avariable2%20%3D%20variable1%3B%20%0A%0A%2F*this%20also%20changes%20variable1%2C%20since%20variable%202%20and%20variable1%0A%20%20%20name%20the%20same%20exact%20object%3A%20*%2F%0A%0Avariable2.set(%22Jack%22%2C%2022)%3B%0A%0ASystem.out.println(variable1)%3B” message=”Java Code” highlight=”” provider=”manual”/] [ad type=”banner”]
  • Let’s just assume that System.out.println method above will print the name and age of a PersonClass object – even though this is not correct, it does keep the example simple and easy to understand. So, if we run the code above, the output will be:

Jack 22

  • In the code above, you can see that when we made a change to variable2, that it also changed variable1. This might confuse you into thinking that because of that fact Java is pass by reference – and you would be very WRONG.
  • Both variable1 and variable2 hold a reference to the same object in memory – and this happened when we ran this line of code “variable2 = variable1″. When we use the assignment operator (the “=”) with variables of a class type, then we are copying that reference value – in other words variable2 is given the memory address (or reference) that is being stored in variable1.
  • Remember that the word reference means the same thing as memory address.

This assignment of references is best displayed by actual drawings, which we show below:

An illustration of pass by value in Java

  • So, looking at the images above it should be clear that variable1 and variable2 are just two different references to the same exact spot in memory. Because of the fact that the statement “variable2 = variable1″ essentially just copies the reference from variable1 into variable2, this is pass by value.
  • You should think of the reference (which is a memory address) as the value, and in this case that reference is what is being copied.
  • And, that is exactly what pass by value means – a copy of a value is passed to another variable.

You should also read our article on the differences between primitive types and reference types here:

  • Primitive type vs Reference type.(http://www.programmerinterview.com/index.php/java-questions/difference-between-a-primitive-type-and-a-class-type/)

[pastacode lang=”java” manual=”%2F%2Fcreate%20an%20object%20by%20passing%20in%20a%20name%20and%20age%3A%0APersonClass%20variable1%20%3D%20new%20PersonClass(%22Mary%22%2C%2032)%3B%0A%0APersonClass%20variable2%3B%0A%0A%2F%2FBoth%20variable2%20and%20variable1%20now%20reference%20the%20same%20object%0Avariable2%20%3D%20variable1%3B%20%0A%0APersonClass%20variable3%20%3D%20new%20PersonClass(%22Andre%22%2C%2045)%3B%0A%0A%2F%2F%20variable1%20now%20points%20to%20variable3%0Avariable1%20%3D%20variable3%3B%0A%0A%2F%2FWHAT%20IS%20OUTPUT%20BY%20THIS%3F%0ASystem.out.println(variable2)%3B%0ASystem.out.println(variable1)%3B” message=”Java Code” highlight=”” provider=”manual”/] [ad type=”banner”]

If we run the code above it will output the code below:

Mary 32
Andre 45

  • The key to understanding the code above is the fact that changing the object that variable1 points to does not change variable2.
  • So, even though variable1 is changed to point to a different object, that has no effect whatsoever on variable2. Hopefully that is clear to you – that variable1 and variable2 are not interchangeable – they are different variables that just store the same value – at least until the “variable1 = variable3” statement.
  • And that should prove to you that Java passes objects by value, and everything else for that matter.

Is it possible to pass an object by reference in Java?

  • No, there are no “extra” language features in Java that would allow for you to pass an object by reference in Java. Java is strictly pass by value, and does not give the programmer the option of passing anything by reference.

Are arrays passed by reference in Java?

  • Arrays in Java are also objects. And what did you learn about objects in Java? Well, that they are passed by value and not passed by reference.
  • And the same is true for arrays in Java – they are passed by value and not by reference. Of course, like any other class object, when an array is passed to another method that method can still change the contents of the array itself.
  • But, what is being passed to the method is a copy of the reference address that points to the array object. Just take a look at our example above for the PersonClass – the same exact principles apply to arrays since they are objects in Java, and are passed by value.

A Note on Remote Method Invocation (RMI)

  • When passing parameters to remote methods, things get a bit more complex. First, we’re (usually) dealing with passing data between two independent virtual machines, which might be on separate physical machines as well.
  • Passing the value of a pointer wouldn’t do any good, as the target virtual machine doesn’t have access to the caller’s heap.
  • You’ll often hear “pass by value” and “pass by reference” used with respect to RMI. These terms have more of a “logical” meaning, and really aren’t correct for the intended use.
  • Here’s what is usually meant by these phrases with regard to RMI.

Note that this is not proper usage of “pass by value” and “pass by reference” semantics:

RMI Pass-by-value

  • The actual parameter is serialized and passed using a network protocol to the target remote object. Serialization essentially “squeezes” the data out of an object/primitive. On the receiving end, that data is used to build a “clone” of the original object or primitive.
  • Note that this process can be rather expensive if the actual parameters point to large objects (or large graphs of objects).
  • This isn’t quite the right use of “pass-by-value”; I think it should really be called something like “pass-by-memento”. (See “Design Patterns” by Gamma et al for a description of the Memento pattern).

RMI Pass-by-reference

  • The actual parameter, which is itself a remote object, is represented by a proxy. The proxy keeps track of where the actual parameter lives, and anytime the target method uses the formal parameter, another remote method invocation occurs to “call back” to the actual parameter.
  • This can be useful if the actual parameter points to a large object (or graph of objects) and there are few call backs.
    This isn’t quite the right use of “pass-by-reference” (again, you cannot change the actual parameter itself).
  • I think it should be called something like “pass-by-proxy”. (Again, see “Design Patterns” for descriptions of the Proxy pattern).

Categorized in: