Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java nested classes: enclosing instances and object lifetime

Last updated: 28 Sept 20263 min read
tutorial
IntermediateBy AITrove Editorial

A static nested class is a member type without an implicit enclosing instance; a non-static inner class is associated with an enclosing object.

Java 8+. Use a JDK that supports this release.

Store only the ownership you need

A shipment snapshot needs an ID and a state. It does not need the entire warehouse service. Making the value type static avoids an implicit route back to an enclosing service instance.

A non-static inner type can access its enclosing object’s members. That can be useful for a short-lived helper, but storing the helper in a long-lived listener registry can also retain the enclosing object and its reachable state.

The sample copies a few immutable values into a static snapshot. Copying a reference to a mutable list would still share its elements; nested-class syntax does not supply a deep-copy operation.

Distinguish visibility from capture

A member class can be private even though a method returns a public representation such as text. Visibility determines who can name or access the type. Static determines whether each instance needs an enclosing instance. Those are different choices.

Local classes and lambdas may capture effectively final local variables. Capturing a reference does not freeze the referenced object. The lambda lesson covers that boundary for callbacks.

Working program

Java
public class WarehouseSnapshot {
    private final String warehouseId;
    WarehouseSnapshot(String warehouseId) { this.warehouseId = warehouseId; }
    static final class ShipmentState {
        private final String id;
        private final String state;
        ShipmentState(String id, String state) {
            this.id = id;
            this.state = state;
        }
        String render() { return id + ":" + state; }
    }
    ShipmentState snapshot(String shipmentId) {
        return new ShipmentState(warehouseId + "/" + shipmentId, "ready");
    }
    public static void main(String[] args) {
        ShipmentState snapshot = new WarehouseSnapshot("north").snapshot("s-54");
        System.out.println(snapshot.render());
    }
}

Output

Output
north/s-54:ready

Cost and design choices

The snapshot stores two references plus ordinary object overhead. Exact byte sizes depend on the VM and reference representation; syntax alone does not determine a portable byte count.

A retained inner instance can keep a larger graph reachable. Assess retained memory, not just shallow object size. Clearing a service reference does not help if another live object still reaches it.

Common Mistakes

  • Do not assume nested means static.
  • Do not capture a service in a long-lived callback without considering lifetime.
  • Do not describe a shallow snapshot as deeply immutable.

Connect the contracts

Compare the boundary explained in Object ownership with the assumptions made by this program.

Compare the boundary explained in Reachability and memory with the assumptions made by this program.

java
nested-classes
Storage details