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
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: