Java: Pass By Value or Pass By Reference
Many programmers often confuse between Java being Passed By Value or Pass By Reference. If only we could visualize our code, this won’t seem too big a problem.
Let’s start with the basics.
Data is shared between functions by passing parameters. Now, there are 2 ways of passing parameters:
- Pass By Value: The pass by value method copies the value of actual parameters. The called function creates its own copy of argument values and then uses them. Since the work is done on a copy, the original parameter does not see the changes.
- Pass By Reference: The pass by reference method passes the parameters as a reference(address) of the original variable. The called function does not create its own copy, rather, it refers to the original values only. Hence, the changes made in the called function will be reflected in the original parameter as well.
Java follows the following rules in storing variables:
- Local variables like primitives and object references are created on Stack memory.
- Objects are created on Heap memory.
Now coming to the main question: Is Java Pass by Value or Pass by Reference?
Java Always follows Pass by Value
Let’s see an example to understand the same:
Explanation:
As java follows pass by value mechanism, the processData function worked on the copy of data. Hence, no change in data was there in the original calling function
Let's see another example:
What happened up there? If Java is passed by Value then why did my original List got updated? 😮 Looks like java is not passed by value after all? 🤔Wrong. Repeat after me
Java Always follows Pass by Value
Explanation:
Consider the following diagram to understand it better.
In the above program, “fruits” is passed to the processData function. “fruitsRef” is a copy of the “fruits” param. Both fruits and fruitsRef are created on Stack. They are two different references. But the interesting point is, it points to the same underlying object in Heap. So any change that you make using one reference is going to impact the common object.
Let’s see one more example:
Explanation:
In this case, we used the “new” operator to change the reference of the fruitsRef variable. fruitsRef now points to a new object and hence any change that you make in this object is not going to impact the original fruits list object.
In conclusion, Java always follows Pass by Value. However, we should be careful while passing object references between methods.
The above concept is very important to correctly implement your problem statements.
For Example: Let's consider a program to delete a node at a given position in a Single Linked List.
Solution:
class Node {
int data;
Node next;
Node(int d){
data = d;
next = null;
}
}class LinkedList { public static Node push(Node head, int data) {
Node newNode = new Node(data);
newNode.next = head;
head = newNode;
return head;
} public static void deleteNode(Node head, int position) {
// List is empty
if (head == null){
return;
}
// If position is 1st, removing head node
if (position == 1) {
head = head.next;
return;
} Node prevNode = head;
int i = 2; while (prevNode != null && i != position) {
prevNode = prevNode.next;
i++;
} // When position is more than number of node
if (prevNode == null || prevNode.next == null) {
return;
} prevNode.next = prevNode.next.next;
} public static void printList(Node head) {
Node currNode = head;
while (currNode != null) {
System.out.print(currNode.data + " ");
currNode = currNode.next;
}
} public static void main(String[] args) {
Node head = null;
head = push(head, 5);
head = push(head, 4);
head = push(head, 3);
head = push(head, 2);
head = push(head, 1);
System.out.println("Created Linked list is: ");
printList(head);
// Delete node at position 2
deleteNode(head, 2);
System.out.println("\nLinked List after Deletion at position 2: ");
printList(head);
}
}
The above solution works in all test cases except one. When you delete the first node i.e. Position=1. Based on the previous section concept, can you now understand why it doesn’t work? Perhaps the following diagram will be of some help 🤓
To correct the above algorithm, we need to do the following:
public static Node deleteNode(Node head, int position) {
// List is empty
if (head == null){
return head;
}
// If position is 1st, removing head node
if (position == 1) {
head = head.next;
return head;
} Node prevNode = head;
int i = 2; while (prevNode != null && i != position) {
prevNode = prevNode.next;
i++;
} // When position is more than number of node
if (prevNode == null || prevNode.next == null) {
return head;
} prevNode.next = prevNode.next.next;
return head;
}public static void main(String[] args) {
Node head = null;
head = push(head, 5);
head = push(head, 4);
head = push(head, 3);
head = push(head, 2);
head = push(head, 1);
System.out.println("Created Linked list is: ");
printList(head);
// Delete node at position 2
head = deleteNode(head, 2);
System.out.println("\nLinked List after Deletion at position 2: ");
printList(head);
}//Rest of the code remains same
In this article, we discussed one small yet significant concept of Java: Parameter Passing. Keep watching this space for more content. Happy reading.