Object References and Their Mechanisms
Object references
Variables that store the memory address of an object rather than the object itself.
Object references are like pointers in languages such as C++ or Golang, where variables can hold the address of primitive value or an object in memory.
- In Java, when you create an object using the new keyword, the variable holds a reference to the object:
Student student1 = new Student("Alice", 16);- Here, student1 is a reference to the Student object.
Sharing References and Modifying Objects
When you assign one object reference to another, both references point to the same object.
public class Student{
public String name;
public int age;
public Student(String nameIn, int ageIn){
this.name = nameIn;
this.age = ageIn;
}
public static void main(String[] args){
Student student1 = new Student("Alice", 13); // initialise object
System.out.println("student1 initial name: " + student1.name + ", age: " + student1.age);
Student student2 = student1; // share reference
System.out.println("student2 initial name: " + student2.name + ", age: " + student2.age);
}
}
Changes made through one reference affect the object and are visible through other references.
public class Student{
public String name;
public int age;
public Student(String nameIn, int ageIn){
this.name = nameIn;
this.age = ageIn;
}
public static void main(String[] args){
Student student1 = new Student("Alice", 13); // initialise object
System.out.println("student1 initial name: " + student1.name + ", age: " + student1.age);
Student student2 = student1; // share reference
System.out.println("student2 initial name: " + student2.name + ", age: " + student2.age);
// change student2 attributes
student2.age = 16;
student2.name = "Bob";
System.out.println("student2 new name: " + student2.name + ", age: " + student2.age);
System.out.println("student1 new name: " + student1.name + ", age: " + student1.age);
}
}
Null References
A reference that does not point to any object is called a null reference.
Student student3 = null;Accessing methods or properties on a null reference will result in a runtime error (e.g., NullPointerException in Java).
Passing References to Methods
When you pass an object reference to a method, the method receives a copy of the reference, not a copy of the object.
public class Student{
private String name;
private int age;
public Student(String nameIn, int ageIn){
this.name = nameIn;
this.age = ageIn;
}
public String getName(){
return this.name;
}
public void setName(String nameIn){
this.name = nameIn;
}
public static void updateName(Student s, String newName)
{
s.setName(newName);
}
public static void main(String[] args){
Student student4 = new Student("Charlie", 17);
System.out.println("Initial name: " + student4.getName());
updateName(student4, "David"); // invoke method
System.out.println("New name: " + student4.getName());
}
}
Immutable Objects
- Some objects, such as strings in Java, are immutable, meaning their state cannot be changed.
- Modifying an immutable object creates a new object.
public class Main{
public static void main(String[] args){
String str1 = "Hello";
String str2 = str1; // share reference
str2 += " World!"; // modify string
System.out.println("str1: " + str1);
System.out.println("str2: " + str2);
}
}
Example of Implementing Linked Lists with References
A linked list is a linear data structure where each element (node) contains a reference to the next node.
One of the possible implementations (from the ground up) of a linked list (limited to the add method):
public class LinkedList{
public static class Node{ // ideally in seperate file
public int value;
public Node next;
}
private Node head; // default null
public void add(Node newNode){
newNode.next = null;
if (this.head == null){ // if list is empty
this.head = newNode; // move head pointer
return; // stop method execution
}
Node currentNode = this.head;
while (currentNode.next != null){ // iterate through until last
currentNode = currentNode.next; // move on to the next node
}
currentNode.next = newNode; // at this point currentNode is last node in the list
}
public void print(){ // iterate through list and output values
String res = "";
if (this.head == null){
System.out.println("List is empty");
return; // stop method execution
}
Node currentNode = this.head;
while (currentNode != null){ // iterate through
res += currentNode.value + " ";
currentNode = currentNode.next; // move on to the next node
}
System.out.println(res);
}
public static void main(String[] args){ // test the code
LinkedList myList = new LinkedList();
myList.print();
for (int i = 10; i <= 50; i+=10){ // populate list
Node newNode = new Node();
newNode.value = i;
myList.add(newNode);
}
myList.print(); // output list
}
}
- In this example, the add method updates the next reference of the last node to point to the new node.
- This demonstrates how references are used to link nodes together.
Swapping references is a common operation in algorithms like sorting.
Swapping nodes in linked list animation
- What happens when you assign one object reference to another?
- How do object references differ from primitive data types?
- Why is it important to understand object references when designing algorithms?
- Try implementing
- remove(int value) function for LinkedList
- a Binary Search Tree and its node insertion in Java.