CodeGym /Courses /JAVA 25 SELF /Static nested classes (static nested)

Static nested classes (static nested)

JAVA 25 SELF
Level 16 , Lesson 1
Available

1. Static nested class

Static nested class (static nested class) is a class declared inside another class with the static modifier. In essence, it is a regular class that simply “lives” inside another class but is not tied to its instance.

If an inner class is like a younger sibling who always holds the older sibling’s hand (an instance of the outer class), then a static nested class is a cousin who only shows up for family holidays and otherwise lives their own life.

Key differences:

  • Has no implicit reference to the outer class instance—no OuterClass.this and no access to non-static members.
  • Can contain static members (unlike a regular inner class).
  • Is instantiated without an instance of the outer class.

Declaration syntax

Declaring a static nested class is straightforward: use the static keyword inside the outer class.

class Outer {
    static class Nested {
        void print() {
            System.out.println("Hello from Nested!");
        }
    }
}

That’s it! No tricky syntax—just static class.

Visualization:

Outer (outer class)
│
├── Nested (static nested class)
│      └── print()

2. Instantiating a static nested class

The nice part: you don’t need an instance of the outer class!

Outer.Nested nested = new Outer.Nested();
nested.print(); // Hello from Nested!

Note: we use the fully qualified name—Outer.Nested. It’s like referring to a nested class via the family name: “Smith.Son.”

Compare with an inner class:

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // an outer object is required

And for a static nested class, an Outer instance isn’t needed at all!

3. Access to members of the outer class

This is where the main difference from an inner class lies.

  • A static nested class has access ONLY to static members of the outer class.
  • It cannot access non-static fields and methods (even if they are public).

Example:

class Outer {
    private static int staticValue = 10;
    private int instanceValue = 20;

    static class Nested {
        void show() {
            System.out.println("Static value: " + staticValue); // OK
            // System.out.println("Instance value: " + instanceValue); // Error!
        }
    }
}

If you try to access the non-static field instanceValue, the compiler will immediately give you a little lecture.

Why so? Because a static nested class doesn’t “know” which Outer instance to bind to—it has no reference to the outer class instance.

4. When to use static nested classes

When are they appropriate?

  • When the nested class is logically related to the outer class but does not require access to the outer class instance.
  • When you want to encapsulate a helper structure: for example, a builder, a utility, an enum, or even a small immutable object.
  • When you need to reduce package clutter: the class is only needed by the outer class, so there’s no point extracting it.

Typical scenarios:

  • The Builder pattern (especially for immutable objects)
  • Implementing helper structures: for example, internal Node classes in collections
  • Grouping constants or utilities

A simple rule of thumb
Ask yourself: “Does my nested class need access to a specific instance of the outer class?”
NO → use a static class (static nested)
YES → use a regular class (inner)

5. Usage examples

Example 1: A Builder for a class

Suppose we have a Person class and want to implement the Builder pattern for it:

public class Person {
    private final String name;
    private final int age;

    // Private constructor
    private Person(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
    }

    // Static nested Builder class
    public static class Builder {
        private String name;
        private int age;

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }

    public void printInfo() {
        System.out.println("Person: " + name + ", " + age);
    }
}

Usage:

Person person = new Person.Builder()
    .setName("Ivan")
    .setAge(30)
    .build();

person.printInfo(); // Person: Ivan, 30

Why is Builder a static nested class?
Because it doesn’t depend on a Person instance; it just helps create one. It is logically related to Person but not to any specific instance.

Example 2: A helper structure inside a collection

Imagine a “box of integers” class where a private static nested Node class is used to store elements:

public class IntBox {
    private Node head;

    // Nested static class
    private static class Node {
        int value;
        Node next;

        Node(int value) {
            this.value = value;
        }
    }

    public void add(int value) {
        Node node = new Node(value);
        node.next = head;
        head = node;
    }

    public void printAll() {
        Node current = head;
        while (current != null) {
            System.out.println(current.value);
            current = current.next;
        }
    }
}

Usage:

IntBox box = new IntBox();
box.add(1);
box.add(2);
box.add(3);
box.printAll(); // 3 2 1

Why is Node static?
Because each Node doesn’t need to know about the entire box (IntBox); it simply stores the data and a reference to the next Node.

Example 3: A utility class inside a main class

public class MathUtils {
    // Static nested class for working with complex numbers
    public static class Complex {
        private final double re;
        private final double im;

        public Complex(double re, double im) {
            this.re = re;
            this.im = im;
        }

        public Complex add(Complex other) {
            return new Complex(this.re + other.re, this.im + other.im);
        }

        @Override
        public String toString() {
            return re + " + " + im + "i";
        }
    }
}

Usage:

MathUtils.Complex a = new MathUtils.Complex(1, 2);
MathUtils.Complex b = new MathUtils.Complex(3, 4);
MathUtils.Complex sum = a.add(b);
System.out.println(sum); // 4.0 + 6.0i

6. Useful nuances

Inner class vs. static nested class

Inner class Static nested class
Keyword none
static
Implicit reference to the outer instance yes no
Access to non-static members of the outer class yes no
Access to static members of the outer class yes yes
May contain static members no (constants only) yes
Instantiation syntax
outer.new Inner()
new Outer.Nested()
Usage When access to the outer instance is needed When access to the outer instance is not needed

Illustration

flowchart LR
    OuterClass -->|has| InnerClass
    OuterClass -.->|has| StaticNestedClass
    StaticNestedClass -.->|can access| staticMembers
    InnerClass -->|can access| instanceMembers
    InnerClass -->|can access| staticMembers

Characteristics and limitations

  • Static nested class can contain both instance and static fields and methods.
  • It can be declared with any access modifier (public, private, protected, package-private).
  • It can implement interfaces and extend other classes.
  • It can be generic.
  • It is commonly used to encapsulate internal helper classes that are not needed outside the outer class.

Example of a generic static nested class:

public class Box {
    public static class Holder<T> {
        private T value;
        public Holder(T value) { this.value = value; }
        public T get() { return value; }
    }
}

When NOT to use a static nested class

  • If the nested class needs access to the outer class’s non-static fields/methods—use a regular inner class.
  • If the class is needed outside the outer class—extract it into a separate file.
  • If the class is too large or complex—make it a top-level class.

7. Common mistakes and nuances

Error #1: Confusing an inner class and a static nested class.
Many beginners try to access non-static members of the outer class from a static nested class. But a static nested class has no reference to the outer class instance, so this is impossible. If you need access to the state of a specific object—use a regular inner class.

Error #2: Attempting to create a static nested class via an instance of the outer class.
There is no need to write outer.new Inner(). For a static nested class, always use new Outer.Nested().

Error #3: Using a static nested class for logic that requires access to the outer class instance.
If the class’s logic is tightly coupled to the state of the outer class’s instance, a static nested class is a poor choice. Use a regular inner class.

Error #4: Overly complex nesting.
Don’t overuse nested classes. If the structure becomes confusing, it’s better to extract some classes to top level.

1
Task
JAVA 25 SELF, level 16, lesson 1
Locked
Wizard's Toolkit: Activating a Spell 🔮
Wizard's Toolkit: Activating a Spell 🔮
1
Task
JAVA 25 SELF, level 16, lesson 1
Locked
Secret Vault: Access Level 🛡️
Secret Vault: Access Level 🛡️
1
Task
JAVA 25 SELF, level 16, lesson 1
Locked
Valuables Accounting: Artifact Chain 💎
Valuables Accounting: Artifact Chain 💎
1
Task
JAVA 25 SELF, level 16, lesson 1
Locked
Publishing House: creating a new book 📚
Publishing House: creating a new book 📚
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION