Item 83: Use lazy initialization judiciously

83. Delayed initialization should be used with caution

// Normal initialization of an instance field
private final FieldType field = computeFieldValue();
// Lazy initialization of instance field - synchronized accessor
private FieldType field;
 private synchronized FieldType getField() {
    if (field == null)
        field = computeFieldValue();
    return field;
}
// Lazy initialization holder class idiom for static fields
private static class FieldHolder {
  static final FieldType field = computeFieldValue();
}
private static FieldType getField() { return FieldHolder.field; }
// Double-check idiom for lazy initialization of instance fields
private volatile FieldType field;
 private FieldType getField() {
    FieldType result = field;
    if (result == null) {  // First check (no locking)
        synchronized(this) {
            if (field == null)  // Second check (with locking)
                field = result = computeFieldValue();
        }
    }
    return result;
}
// Single-check idiom - can cause repeated initialization!
private volatile FieldType field;
 private FieldType getField() {
    FieldType result = field;
    if (result == null)
        field = result = computeFieldValue();
    return result;
}

Recommended Posts

Item 83: Use lazy initialization judiciously
Item 52: Use overloading judiciously
Item 53: Use varargs judiciously
Item 45: Use streams judiciously
Item 66: Use native methods judiciously
Item 67: Optimize judiciously
Item 55: Return optionals judiciously
Item 26: Don't use raw types
Item 32: Combine generics and varargs judiciously
Item 59: Know and use the libraries
Item 40: Consistently use the Override annotation