Java > Core Java > Variables and Data Types > Reference Data Types (String, Arrays, Objects)

Object Creation and Reference Assignment

This snippet demonstrates how objects are created in Java and how references are assigned. It also highlights the concept of multiple references pointing to the same object.

Code Example

This code creates two `Person` objects. The first object is created and its reference is assigned to `person1`. Then, the reference of `person1` is assigned to `person2`. When we modify `person2`'s age, it also affects `person1` because they both point to the same object in memory. Finally `person3` is created and the comparison between object is performed

public class ObjectReferences {
    public static void main(String[] args) {
        // Creating a Person object
        Person person1 = new Person("Bob", 25);
        System.out.println("person1: " + person1.getName() + ", " + person1.getAge());

        // Assigning the reference of person1 to person2
        Person person2 = person1;
        System.out.println("person2: " + person2.getName() + ", " + person2.getAge());

        // Modifying person2's age
        person2.setAge(26);

        // Printing person1's age - it has also changed!
        System.out.println("person1 (after modifying person2): " + person1.getName() + ", " + person1.getAge());

        // Creating a new Person Object
        Person person3 = new Person("Charlie", 30);
        System.out.println("person3: " + person3.getName() + ", " + person3.getAge());

        // Check if person1 and person2 refer to the same object.
        System.out.println("person1 == person2: " + (person1 == person2)); // Output: true

        //Check if person1 and person3 refer to the same object
        System.out.println("person1 == person3: " + (person1 == person3)); // Output: false
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Concepts Behind the Snippet

  • Object Creation: Objects are created using the `new` keyword.
  • Reference Assignment: When you assign one object variable to another, you are assigning the reference (memory address) of the object, not creating a new copy of the object.
  • Multiple References: Multiple references can point to the same object in memory. Changes made through one reference are visible through all references pointing to the same object.
  • Comparing Object References: The `==` operator compares object references, not the contents of the objects. To compare the contents, you typically override the `equals()` method.

Real-Life Use Case

In a GUI application, you might have multiple components (e.g., buttons, text fields) referencing the same data model. If one component modifies the data model, all components referencing the model will reflect the changes.

Best Practices

  • Understanding Aliasing: Be aware of aliasing (multiple references to the same object) and its implications when modifying objects.
  • Defensive Copying: If you need to ensure that modifications to one object do not affect another, create a copy of the object (e.g., using a copy constructor or cloning).
  • Overriding equals() and hashCode(): If you need to compare objects based on their content, override the `equals()` and `hashCode()` methods in your class.

Interview Tip

Be prepared to explain the difference between passing objects by value and passing objects by reference (Java always passes objects by reference value). Also, understand the concept of garbage collection and how it reclaims memory occupied by objects that are no longer referenced.

When to Use Them

Reference assignment is fundamental to object-oriented programming. It allows you to share data and behavior between different parts of your application. Be mindful of the implications of shared references when designing your data structures and algorithms.

Memory Footprint

Each object occupies space on the heap. The size depends on the object's fields. References themselves are relatively small (typically 4 or 8 bytes, depending on the architecture), but they point to potentially large objects in memory.

Alternatives

If you need to avoid aliasing, consider creating copies of objects. Techniques include:

  • Copy Constructors
  • Cloning (implementing the `Cloneable` interface)
  • Serialization/Deserialization
  • Using libraries like Apache Commons Lang's `SerializationUtils.clone()`

Pros

  • Efficiency: Sharing references avoids unnecessary copying of data.
  • Data Consistency: Changes made through one reference are immediately visible through all other references.

Cons

  • Unexpected Side Effects: Modifying an object through one reference can unintentionally affect other parts of the application that are referencing the same object.
  • Debugging Challenges: Tracking down the source of a modification when multiple references exist can be difficult.

FAQ

  • What is the difference between `==` and `equals()` when comparing objects in Java?

    The `==` operator compares object references, checking if they point to the same memory location. The `equals()` method, when overridden, compares the contents of the objects based on a specific criteria. If `equals()` is not overridden, it defaults to comparing references (like `==`).
  • How can I create a copy of an object in Java?

    You can create a copy using several techniques: a copy constructor, cloning (implementing `Cloneable`), or serialization/deserialization. Each approach has its own considerations regarding deep vs. shallow copying.
  • What is a null reference?

    A null reference is a reference that does not point to any object. Accessing a member of a null reference will result in a `NullPointerException`.