Understanding “Call by Value” and “Call by Reference” in Java

Are you learning Java but confused by the different ways to call methods? Do you want to better understand “Call by Value” and “Call by Reference”? Then you are at the right place. These concepts are a major point of confusion for those learning Java, but if you develop a clear understanding of “Call by Value” and “Call by Reference,” you will be able to apply these concepts to other object-oriented programming languages like C and C++. 

This guide will explain what these two terms mean and provide code examples to enhance your understanding. You’ll find comparisons between the two call methods and learn the best practices for both.

Java is relevant again

In many ways, the Java programming language is experiencing a resurgence. According to Stack Overflow’s Developer Survey of 2021, Java is currently the 5th most popular programming language. Created in 1991, Java dominated the software development market for over 20 years. But in recent years, Java’s popularity has been declining in favor of newer technologies like Python and JavaScript.

Mobile phone ownership, particularly of Android devices, is increasing rapidly across the world.  And countries with emerging economies are experiencing the highest new user rates. With a growing pool of smartphone users, the need for new Android apps grows as well. Java is becoming relevant again because it is the official language of Android application development. 

Java is a great object-oriented programming language to learn. It is intuitive, and because of JVM or the Java Virtual Machine, you can easily move code across computer systems without rewriting it.

Background and definitions 

Let’s provide some background information and definitions for a few of the terms associated with this topic. 

When discussing “Call by Value” and “Call by Reference,” don’t get confused if you see “Pass by Value” or “Pass by Reference.” These terms are synonymous, and people may use them interchangeably.

Method: A section of code that has to be called to be executed.

Class: The basic code template used when creating objects

Objects: Created during runtime from a class – an instance of a class.

Parameter: A specific piece of information that is passed into a method. Parameters can come in two forms:

  • Primitive types: integers, boolean, float, byte, char
  • Reference types: everything else, including objects and strings

Formal parameter: The variables defined by the function that receives values when the function is called.

Actual parameter: The value passed to a function. 

What does “Call by Value” mean?

Call by Value means that a parameter or argument expression is evaluated. The parameter value is then copied into a location, or a spot in memory, during the execution of a method or function. A complete copy is passed, not the memory address. 

When using “Call by Value,” any changes to the copied value will not impact the original parameter value. This is the default for a variety of programming languages, including C++, PHP, and C#.

What does “Call by Reference” mean?

‘Call by Reference’ means that a parameter acts as an alias for the actual parameter. The parameter value stands in place during the execution of a method or function. The function has the memory address, and any changes resulting from the function will change the reference parameter. 

Pointers are needed to access the address of a variable. Java was intentionally created without traditional pointers because pointers can be risky in the wrong hands. Instead, Java uses a term called “references,” which was mentioned previously in the background section. If you are comfortable with the concept of pointers, consider these “references” to be pointers, and the semantics will be less confusing.

Does Java use “Call by Value” or “Call by Reference”?

Java ALWAYS uses “Call by Value,” 100% of the time. While this seems straightforward, there is more nuance involved. 

Because Java does not have true pointers, and all “Call by Reference” need pointers to provide the memory location, Java does not use true “Call by Reference.” Objects act as if they are passed with “Call by Reference.”

Let’s break that down for you to understand better. In Java, there are three different ways to use “Call by Reference” in an indirect way. Changes to an object within a method WILL affect the argument object:

  • Make the member variable public.
  • Return a value from a method.
  • Create a single element array and pass it as a parameter.

We will cover each of these special use cases in the example section for “Call by Reference.”

Call by Value syntax

The general syntax for “Call by Value” is demonstrated below. This syntax is standard across multiple programming languages, with minor variations.

Function: Function_name(parameter1, parameter2)
{
Int variable_name1;
Int variable_name2;
}

 

Call by Value examples

“Call by Value” is easier to understand because it is straightforward. The parameter is being copied into the method. Within the method, the parameter can change, but the original value of the parameter will be retained in the memory location.

Let’s examine this code example. The argument value will be passed to the method’s parameter, using “Call by Value”:

package example; 
public class CallbyValue 
{ 
  int change(int x) 
  { 
    ++x; // Changes will be in the local variable only. 
    return x; 
  } 
public static void main(String[] args) 
{ 
// Create an object of class. 
    CallbyValue obj = new CallbyValue(); 
     int y = 10; 
     int z = obj.change(y); 
     System.out.println("Value of y after passing: " +y); 
     System.out.println("Value of z after modifying: " +z); 
 } 
}

Output:

Value of y after passing: 10 
Value of z after modifying: 11

In this example, the argument value for the change() method, is int x. X refers to a copy of y from the object, CallbyValue. This copy of y is kept in memory before being passed to the change() method as x

When the change() method is executed, it modifies the copy of y. The original object is not altered. This protects the integrity of objects within Java. So, ++x will increase the x, the copy of y, by 1. 

When x is returned, it will hold a value of 11. This value is attached or stored to the x variable when the method is executed.

Call by Reference examples 

Because you cannot use “Call by Reference” with Java, Java will still call by value when reference variables are passed in. This will create a copy of the reference, and any changes will not be reflected in the original reference. You can get around this in three different ways:

1. Public member variable

When using this technique, you are passing the object of a class into the method, in this case the add() method. The public member variable, x, is updated, and the memory address was changed. 

public class Java {
     
    // making a public member variable
    public int x;
     
    public Java() {
        x = 10;
    }
     
    public static void main(String[] args) {
 
        Java jav = new Java();
         
        // Before calling the add() method
        System.out.println("Before calling method: " +jav.x);
         
        // calling method
        add(jav);
         
        // After calling the add() method
        System.out.println("after calling method: " +jav.x);
         
    }
     
    // add() method starts here that increments 'x' by 1
    public static void add(Java obj) {
        obj.x++;
    }
     
}

Output:

Before calling method: 10
After calling method: 11

2. Return value from method

public class Example {
     
    /*
     *  The original value of 'a' will be changed as we are trying
     *  to pass the objects. Objects are passed by reference.
     */
     
    int x = 10;
    void call(Java jav) {
        jav.x = jav.x+10;
    }
     
    public static void main(String[] args) {
 
        Java jav = new Java();
        System.out.println("Before calling method: " + jav.x);
         
        jav.call(jav);
        System.out.println("After calling method: " + jav.x);
         
         
    }
}

Output:

Before calling method: 10
After calling method: 11

3. Single element array passed as parameter

public class Example {
     
    public static void main(String[] args) {
         
        // single element array
        int a[] = {10};
         
        // Before calling the add() method
        System.out.println("Before calling method: " +a[0]);
         
        // calling method
        add(a);
         
        // After calling the add() method
        System.out.println("after calling method: " +a[0]);
         
    }
     
    // add() method starts here that increments 'a' by 1
    public static void add(int a[]) {
        A[0]++;

  }
}

Output:

Before calling method: 10
After calling method: 11

Summary: “Call by Value” vs “Call by Reference” explained

All programming languages have functions that accept parameters. The “Call by Value” and “Call by Reference” terms are universal concepts in programming but may be applied slightly differently depending on the language in question. If you can develop a good understanding of these concepts now, it will help you later in your programming endeavors. 

The most important point to understand is that Java never provides the program with direct access to change the value of an object. Objects in Java are always accessed through a reference. This was an intentional design point for Java developers to provide program security and allow JVM to function correctly. 

But this remains one of the most commonly misunderstood areas for those learning Java because the terminology is confusing. The use of the term “reference” can make it very confusing if you are coming from another programming language, like C++ or C#. 

If you are still confused on this topic, make sure you have closely examined the code examples and understand what is happening. If you are a visual learner that needs each coding step broken down and explained, check out YouTube videos covering the topic of “Call by Value” vs “Call by Reference” in Java for more information.

Leave a Comment