Concepts / Creating Objects with new

Creating Objects with new

An object is garbage when no variable refers to it, and the system reclaims its memory

  • Programming

Predicting What a Variable Holds

Most of the work you have done with objects so far has been about creating them. Java also has to handle the other end of an object's life: what happens when the object is no longer needed. In Java that destruction happens automatically, not through an instruction the programmer writes. Because nothing in your code says delete this object, it is tempting to assume that one particular action, such as assigning null to a variable, is what tears the object down. This section tests that belief.

Consider a variable std declared with the class type Student. The program runs the single statement std = new Student();. Before reading any further, commit to an answer. Does std hold the Student object itself, or does it hold something that leads to the object? Choose an answer now, even if you are unsure. Your answer will be tested against the explanation in the sections that follow.

What do you think happens?

After the statement std = new Student(); finishes, what does std hold?

  • The Student object itself, stored inside the variable

  • A reference that points to the Student object, which lives separately in the heap

Reveal answer
Answer:

A reference that points to the Student object, which lives separately in the heap.

The variable holds a reference, also called a pointer, to the object. The object itself lives in the heap, and the variable and the object are two separate things joined by a link. The variable is not a container the object sits inside.

Why a Variable Is Not a Box

Many beginners picture a variable as a labeled box that holds an object. In that picture, the Student sits inside a box named std. The picture feels natural, but it fails in exactly the places where programs behave in surprising ways. A more accurate model separates two things. The variable holds a reference, which is also called a pointer, and that reference refers to an object. The object lives in the heap, a region of memory separate from the variable.

stdholds a referenceStudent objectlives in the heaprefers to
When Java runs std = new Student();, where does the object live, where does the variable live, and how are they linked?

The arrow in the diagram carries the important idea. It shows that std refers to the object. The object is not drawn inside the variable, because the variable does not contain it. If you catch yourself saying that the object is stored in std, replace that sentence with one saying that std refers to the object. That wording matches how the rest of this article uses the terms.

What the new Operator Does

The new operator is the mechanism that brings an object into existence. When you write new followed by a class name and parentheses, the operator does two things. It creates an object that is an instance of that class, and it returns a reference to that object. The returned reference is the value that gets stored in the variable. The created object is a separate thing from the reference that points to it.

java
Notes on the code
  • Student is the class type of the variable std
  • new creates an instance of Student and returns a reference to it
  • The = stores the returned reference in std, not the object itself

The operator also does more work behind the scenes. It calls a special subroutine defined in the class, called a constructor. The constructor is the part of the class responsible for setting up a new instance. You do not call the constructor as a separate step. The new operator invokes it as part of creating the object.

  1. 1
    Java reads the new operator together with the class name and parentheses.
  2. 2
    The new operator hands control to the class's constructor.
  3. 3
    The constructor finishes setting up the new object, which is an instance of the class.
  4. 4
    A reference to the finished object is returned.
  5. 5
    The returned reference is assigned to the variable, which is the last participant in the chain.

Read these steps as a sequence of messages rather than a single action. The variable is the last participant in the chain, and it receives a reference, not the object. This is why the variable can be reassigned to point somewhere else without touching the object it used to refer to.

Tracing a Reassignment to null

The source uses a deliberately simple pair of statements. The first line creates a Student object and stores a reference to it in std. The second line overwrites std with null. Focus on what the variable std refers to after each line, rather than on the Student object itself.

java
Notes on the code
  • After line 1, std refers to the new Student object
  • After line 2, std refers to nothing, because it was overwritten with null
  • The Student object still exists in memory after line 2; it is now inaccessible
Worked example

Tracing What std Refers To

Follow the variable std through the two statements and state what it refers to after each line.

  1. 1
    After line 1

    std = new Student() creates a Student object and stores a reference to it in std. std refers to the object.

  2. 2
    After line 2

    std = null overwrites the reference. The variable now refers to nothing. The assignment changed the variable, not the object.

  3. 3
    Status of the object

    The object is still in memory but no variable refers to it, so it has become inaccessible. Java describes such an object as garbage.

Result

After line 2, std refers to nothing, and the Student object is garbage that the system can reclaim.

Several References to One Object

After an object has been used for a while, several variables may refer to it. The object becomes garbage only once every one of those references has been dropped. The following sequence is an original illustration of that idea, not a line from the source. Trace it one statement at a time.

Code walkthrough
Dog a = new Dog();
Dog b = a;
b = new Dog();
a = null;
  1. 1
    Line 1 the new operator creates Object 1 and returns a reference, which is stored in a.
  2. 2
    Line 2 the reference in a is copied into b. No new object is created, so both variables refer to Object 1.
  3. 3
    Line 3 new creates Object 2 and its reference replaces the value in b. Object 1 is still referred to by a.
  4. 4
    Line 4 a is overwritten with null. Nothing refers to Object 1 any more, so it is garbage. Object 2 is still referred to by b and is not garbage.
  • Object 1 is created and a refers to it
  • b is given the same reference as a, so both refer to Object 1
  • b is overwritten with a reference to a newly created Object 2
  • a is overwritten with null; Object 1 now has no references
anullbDog object 2
After the final statement a = null;, which object does each variable refer to?
Referred to by aafter a = new Dog()Referred to by a andbafter b = aReferred to by a onlyafter b = new Dog()Garbageno references remainb = ab = new Dog()a = null
What happens to the status of Dog object 1 when its last reference is reassigned?

Dangling Pointers and Memory Leaks

The source describes two errors that arise in languages where the programmer must delete unused objects. In those languages, manual deletion can go wrong in two opposite ways. A dangling pointer error happens when a programmer deletes an object that still has references to it, so the program later tries to use something that is no longer there. A memory leak happens when a programmer neglects to delete an object that is no longer in use, so memory fills with objects that nothing can reach. One error deletes too early, and the other deletes too late or never.

FeatureDangling pointer errorMemory leak
What goes wrongAn object is deleted while it is still referencedAn unused object is never deleted
What the variable refers toA reference to an object that no longer existsNo variable refers to the unused object
Memory still reservedThe program tries to use memory that is no longer validUnreachable objects keep occupying memory
Root causeDeleting too earlyDeleting too late or never

Two manual-deletion errors described in the source, and how they differ

In Java, the source states that garbage collection is the system's responsibility rather than the programmer's. Because the collector decides which objects are garbage, these two errors are not possible in the same way. The programmer's job shifts from tracking deletions to making sure that objects still needed remain referenced and that finished objects are no longer referenced.

Mistakes When Reading Reference Code

  • Common mistake

    Picturing the object stored inside the variable

    What it looks like

    Believing that after Student std = new Student(); the Student sits inside a box named std.

    Why it fails

    The variable holds a reference that points to the object. The object lives in the heap, separate from the variable.

    Do this instead

    Say that std refers to the object.

  • Common mistake

    Assuming that assigning null destroys the object

    What it looks like

    Expecting the Student object to disappear the moment std = null; runs.

    Why it fails

    Assigning null removes one reference. The object is only garbage if no other reference to it remains.

    Do this instead

    Check whether any other variable still refers to the object before deciding it is garbage.

  • Common mistake

    Thinking that copying a variable copies the object

    What it looks like

    Believing that after Dog b = a; there are now two Dog objects.

    Why it fails

    No new object is created by a copy of a reference. Both variables refer to the same object.

    Do this instead

    Only the new operator creates an object. Assignment between references only copies the reference.

  • Common mistake

    Forgetting that the constructor runs as part of new, not as a separate step

Practice: Predicting References

MEDIUM

Trace the following statements. After each line, state what a refers to and what b refers to, and say whether the first Dog object is garbage after the final line. Dog a = new Dog(); then Dog b = a; then a = new Dog(); then b = null;

Hints
  • Track the first object separately: which variables refer to it after line 2?
  • Line 3 changes a only. Does b still refer to the first object?
  • After line 4, check whether any variable still refers to the first object.

Key Takeaways

  • A variable holds a reference that points to an object; the object itself lives in the heap, separate from the variable.
  • The new operator creates an instance of a class, calls its constructor as part of that work, and returns a reference that is stored in the variable.
  • Reassigning a variable, including setting it to null, removes one reference; an object becomes garbage only when no reference to it remains.
  • Dangling pointer errors and memory leaks are the two errors manual deletion can cause; in Java, garbage collection is the system's responsibility, so the programmer focuses on which references exist.