able—is decremented. Say that size is decremented from 5 to 4. Now whatever is stored in
elementData cannot be accessed: it is beyond the valid size of the array.
elementData is, in this case, a stale reference. The elementData array is probably going
to remain active for a long time, and so anything that it no longer needs to reference needs to
be actively set to null .
This notion of stale references is the key: if a long-lived class caches and then discards object
references, care must be taken to avoid stale references. Otherwise, explicitly setting an ob-
ject reference to null will offer little performance benefit.
1. Use lazy initialization only when the common code paths will leave variables un-
2. Lazy initialization of thread-safe code is unusual but can often piggyback on ex-
3. Use double-checked locking for lazy initialization of code using thread-safe ob-
Immutable and Canonical Objects
In Java, many object types are immutable. This includes objects that have a corresponding
primitive type— Integer , Double , Boolean , and so on—as well as other numeric-based
types, like BigDecimal . The most common Java object, of course, is the immutable String .
From a program design perspective, it is often a good idea for custom classes to represent
immutable objects as well.
When these objects are quickly created and discarded, they have a small effect on young col-
lections; as we saw in Chapter 5 , that impact is limited. But as is true of any object, if a large
number of immutable objects are promoted to the old generation, performance can suffer.
Hence, there is no reason to avoid designing and using immutable objects, even if it may
seem a little counterproductive that these objects cannot be changed and must be re-created.
But one optimization that is often possible when handling these objects is to avoid creating
duplicate copies of the same object.