Passing by Value vs. by Reference Visual Explanation

Pass by Value vs Reference Animation
Think of the coffe in the cup as the data in a variable. One is a copy and one is the original

 

 

When writing software code, you will spend a lot of time defining, reading and changing variables. Using a variable means you use a descriptive word in your code which holds some information (a number, some text, an object, etc.). This descriptive word is the “title” of the stored information. For example:

Variables give you the comfort that you do not have to know where your data is stored in your computers memory. You define a variable, make your calculations and pass the variable from one function to another, and your operating system automatically deals with where your data is physically located.
However, sometimes it is very useful to know what happens behind variables. Especially in lower-level languages (for example Assembler, or C in some circumstances), it is sometimes even necessary to know where a value is stored in memory. This article will explain how variables are passed around between functions, and specifically explains how it works in Java. In Java, there is a slight but important difference of passing by value and passing by reference.

This article will use a simplified syntax in the code examples, since the theory of passing values is applicable to most programming languages.

Passing a variable

The term “passing a variable” is used when a function is called with a variable you defined previously. Let’s look at the following example:

The variable myAge is “passed” to the function calculateBirthYear. The function can then use that variable, for example:

There are two possibilities how you could have passed the variable myAge to the function. The terms “pass by value” and “pass by reference” are used to describe how variables are passed on. To make it short: pass by value means the actual value is passed on. Pass by reference means a number (called an address) is passed on which defines where the value is stored.

How memory works

A basic knowledge of how memory works and how your variables are stored in memory will help to better understand this topic. Since an actual physical memory is hard to draw and different memory types look different (a hard disc vs. RAM for example), it is useful to have an abstract and simple way to imagine how memory looks like.

This article uses a simple and easily understandable approach to explain how values are stored in memory. For most uses (especially for programming beginners), it is enough to understand the concepts. However, once one gets experienced in programming, it is very useful to know more about different memory types and memory regions (harddrives, RAM, heap, stack, etc.).

How memory works
Blocks in memory with their address and two example values

To make it simple, lets think of memory as many blocks which are next to each other. Each block has a number (the memory address). If you define a variable in your code, the value of the variable will be stored somewhere in the memory (your operating system will automatically decide where the best storage place is). The illustration on the right shows a part of some memory. The gray numbers on top of each block show the address of the block in memory, the colored numbers at the bottom show values which are stored in memory.

Taking the previous examples again, the variables myAge and month are defined in your code, and they will be stored in memory as shown in the illustration on the right. As example, the value of myAge is stored at the address 106 and the value of month is stored at the address 113.

Pass by value

Passing by value means that the value of the function parameter is copied into another location of your memory, and when accessing or modifying the variable within your function, only the copy is accessed/modified and the original value is left untouched. Passing by value is how your values are passed on most of the time.
The following example shows a variable passed by value:

Pass by value
The value in the memory is copied to another location to be used within the function

As soon as your software starts processing the calculateBirthYear function, the value myAge is copied to somewhere else in your computers memory. To make this more clear, the variable within the function is named age in this example.

Everything that is happening now with age does not affect the value of myAge (which is outside of calculateBirthYear‘s function scope) at all.

So how do you modify/update a variable outside of your function? When passing a variable by value, the only way to update the source variable is by using the returning value of the function. This means that only one value can be changed outside of the function.

A very simple function for demonstration:

In your code, the source variable is updated with the return value of the function.

Resulting value
Memory after updating the variable

The variable myAge now holds the value 15 (see illustration on the right).

Pass by reference

Passing by reference means that the memory address of the variable (a pointer to the memory location) is passed to the function. This is unlike passing by value, where the value of a variable is passed on. In the examples, the memory address of myAge is 106. When passing myAge to the function increaseAgeByRef, the variable used within the function (age in this example) still points to the same memory address as the original variable myAge (Hint: the & symbol in front of the function parameter is used in many programming languages to get the reference/pointer of a variable).

When calling the function, the value of myAge is changed directly through its reference.

Resulting value
Memory after altering the variable through its reference

The value of myAge is now 15.

With passing by reference, it is now possible to change more than one variable given in the function parameter. In addition, one variable can be returned through the functions return value (often a status, success/fail or the most important variable). For example:

(Hint: The & symbol returns the address of a variable, the * symbol returns what is stored at the address value, “reversing” the & symbol)

To make a decision whether to use pass by reference or pass by value, there are two simple general rules:

  • If a function should return a single value: use pass by value
  • If a function should return two or more distinct values: use pass by reference

Pass by reference can often be avoided by using arrays or structures (or objects in high-level languages).

Java passes by value

Java is a high-level programming language. This means that in normal circumstances you do not have to worry about what happens in memory (and the previous topics are not essential for Java programming, but very useful for general understanding). Mainly because primitives (like int, double, etc.) are always passed by value, and there is no & operator in Java to get their address. Furthermore, variables are often “packed” in a object and object variables are passed around. Regarding the topic of variable passing in Java, there is one simple statement:

Java ALWAYS passes by value.

If you assign a value (or object) to a parameter variable within a method, the variable outside of the method still has the same value (or object). Here is a simple example to test this:

When running this code, the object data output will be the same both times even though the variable is modified within the testMethod method. This simple test shows that the variable someObject is passed by value and not by reference. It shows that the variable object must be in a different location in memory, because when its value is changed, the value of the source variable someObject stays unchanged.
A false argument used often to explain that Java does pass by reference is that the object can be modified within the method, for example with

This, however, changes a object property and not the value of the variable object. The value of the variable object stays the same.

Java object variables

To further explore the subject, object variables must be looked at in more detail. An object variable would be something like

Object value
Java object variables

(The same applies to any other object, like Strings for example). The detail here is that the variable someObject does not hold the object itself, the value of the variable is the pointer to the object. For example as shown in the illustration on the right (using a single memory block for simplicity), the value of someObject is 121. This can be confusing because when calling a method like

the number 121 is passed to the method and it looks like “pass by reference”. However, the value 121 stored in the variable someObject is passed on, and not a pointer to where the value 121 is stored in memory. An implementation example:

On the first line, the passed on variable is the object “object 1” from someObject and its name is changed to “o1”. Then, a new object “object 2” is assigned to the variable obj (color change for clarity) and on the following line that new objects name is set to “o2”. The variable someObject still has the name “o1”.
This brings up another statement in addition to the earlier statement:

In Java, object references (pointers) are passed by value

 

This closes the topic of variable passing in Java. When working with pointers, very abstract thinking is often needed to understand the program logic (and surprising things can happen when modifying the pointer instead of the value). This is why higher level programming languages try to hide that complexity to let you focus on other things.