Creating Objects with new
An object is garbage when no variable refers to it, and the system reclaims its memory
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?
Reveal 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.
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.
- 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.
- 1Java reads the new operator together with the class name and parentheses.
- 2The new operator hands control to the class's constructor.
- 3The constructor finishes setting up the new object, which is an instance of the class.
- 4A reference to the finished object is returned.
- 5The 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.
- 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
Tracing What std Refers To
Follow the variable std through the two statements and state what it refers to after each line.
- 1After line 1
std = new
Student()creates a Student object and stores a reference to it in std. std refers to the object. - 2After line 2
std = null overwrites the reference. The variable now refers to nothing. The assignment changed the variable, not the object.
- 3Status 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.
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.
Dog a = new Dog();
Dog b = a;
b = new Dog();
a = null;- 1Line 1 the new operator creates Object 1 and returns a reference, which is stored in a.
- 2Line 2 the reference in a is copied into b. No new object is created, so both variables refer to Object 1.
- 3Line 3 new creates Object 2 and its reference replaces the value in b. Object 1 is still referred to by a.
- 4Line 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
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.
| Feature | Dangling pointer error | Memory leak |
|---|---|---|
| What goes wrong | An object is deleted while it is still referenced | An unused object is never deleted |
| What the variable refers to | A reference to an object that no longer exists | No variable refers to the unused object |
| Memory still reserved | The program tries to use memory that is no longer valid | Unreachable objects keep occupying memory |
| Root cause | Deleting too early | Deleting 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 likeBelieving that after Student std = new Student(); the Student sits inside a box named std.
Why it failsThe variable holds a reference that points to the object. The object lives in the heap, separate from the variable.
Do this insteadSay that std refers to the object.
Common mistake Assuming that assigning null destroys the object
What it looks likeExpecting the Student object to disappear the moment std = null; runs.
Why it failsAssigning null removes one reference. The object is only garbage if no other reference to it remains.
Do this insteadCheck 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 likeBelieving that after Dog b = a; there are now two Dog objects.
Why it failsNo new object is created by a copy of a reference. Both variables refer to the same object.
Do this insteadOnly 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
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.