Pretty Computer Chips
Image by Jonas Svidras at https://stocksnap.io/photo/intel-8008-LBYK1XTHFC.

Passing a variable by value vs. reference

In programming, a concept that usually creates a lot of confusion among those new to it is the concept of passing a variable by value, versus passing a variable by reference. The 2 examples below illustrate the difference between these two ways variables can be passed in Java:

Passing by value

int a = 18;
int b = a;
a = 21;

// The value of <b> will remain 18, because
// changing <a> does not change <b>.
System.out.println(b);

Passing by reference

int[] a = {18, 19, 20};
int[] b = a;
a[0] = 21; // Changing a value in array <a>.

// The value of b[0] will be 21, because
// <a> and <b> refer to the same array.
System.out.println(b[0]);

The key differences between passing by value and passing by reference lie in the way 2 variables equate to each other. When passing by value, setting b = a is essentially equating the same as equating b = 18, as a = 18. This is why this method of assigning a variable is known as passing by value, because the value that an existing variable holds is passed over to another variable (or function).

When passing a value by reference, setting b = a is not the same as setting as setting b = {18, 19, 20}. Essentially, setting b = a causes both variables a and b to point to the same object in memory. This is why changing a value in a (i.e. a[0]) affects the content of b. Both variables are referring to (and manipulating) the same object!

When are each of them used?

As a rule of thumb, across programming languages, only primitive data types are usually passed by value (i.e. value types), while most of all other types are passed by reference (i.e. reference types). One exception to this rule is the String type in Java — which, for practical intents and purposes — can be considered as being passed by value in Java.

String x="Hello";
String y=x;
x = "new";
System.out.println(y); // Outputs "Hello"

In Java, String is not a primitive type, although they have many attributes of primitives, such as being passed by value, and being able to be literally represented. Look at this Stack Overflow topic if you’re interested to learn more.


Article continues after the advertisement:


Common examples of reference types

In one of the examples above, we used an array as an example of a type that passes by reference. Below are some other examples of types that are also passed by reference.

The codes below are designed to be copy and pasted into a Java file, and they can be run directly. Don’t have Java in your computer? You can also use this online Java compiler to test it out.

Collections (such as Lists, Queues and ArrayLists)

CollectionsReferenceTest.java

import java.util.Arrays;
import java.util.ArrayList;

public class CollectionsReferenceTest {
	public static void main(String args[]) {
		// Creates an array list with the values [1, 2, 3].
		ArrayList<Integer> a = new ArrayList<Integer>() {
			{
				add(1);
				add(2);
				add(3);
			}
		};

		// Assigns <b> to <a>.
		ArrayList<Integer> b = a;

		// Changes the value of 1 (index 0) in the list to 10 in <a>.
		a.set(0, 10);

		// Prints the set of values in <b>. Result: [10, 2, 3]
		System.out.print(Arrays.toString(b.toArray()));
	}
}

Scanner objects

ScannerReferenceTest.java

import java.util.Scanner;
public class ScannerReferenceTest {
	public static void main(String args[]) {
		// Create a scanner <s> and reference <t> to it.
		Scanner s = new Scanner(System.in);
		Scanner t = s;

		// Both <s> and <t> can be used interchangeably to collect input.
		System.out.println("Please enter your name:");
		String name = s.nextLine();
		System.out.println("Please enter your age:");
		int age = t.nextInt();

		// Prints the user's name and age.
		System.out.printf("Hi %s, you are %s years old this year.", name, age);
	}
}

Article continues after the advertisement:


User-defined objects

Here, we create a class that defines a custom type named Member.

As there are 2 script files in the below program, you’ll have to use a version of the online Java compiler that supports multiple files to test these scripts out.

Member.java

import java.util.Scanner;
public class Member {

	// Define the fields in a Member object.
	public String name;
	public int rank;
	
	// The constructor for Member allows us to define its name and rank.
	public Member(String n, int r) {
		name = n;
		rank = r;
	}
}

If we reference 2 variables to the same Member object, you can clearly see they refer to the same member:

MemberReferenceTest.java

import java.util.Scanner;
public class MemberReferenceTest {
	public static void main(String args[]) {
		// Create a new Member and 2 references
		Member m = new Member("Jane", 5);
		Member n = m;

		// Change the name and rank of Member <m>.
		m.name = "John";
		m.rank = 10;

		// The name and rank of Member <n> is also changed.
		System.out.printf("Member Name: %s%n", n.name);
		System.out.printf("Member Rank: %s%n", n.rank);
	}
}

Conclusion

I hope this article helped to make it easier to understand and differentiate between value types and reference types. Feel free to leave your questions in the comments section below, if you have any more questions regarding this.


Article continues after the advertisement:


Leave a Reply

Your email address will not be published. Required fields are marked *

Note: You can use Markdown to format your comments.

This site uses Akismet to reduce spam. Learn how your comment data is processed.