Nested Classes

In Java, you can define a class inside another class. These are called nested classes.

class OuterClass {
    class NestedClass {
        // inner logic here
    }
}

But what’s the point of nesting classes? And how many types are there?

Let’s break it down


Types of Nested Classes

Nested classes are divided into two main categories:

Category Type
Non-static Inner Class
Static Static Nested Class
class OuterClass {
    class InnerClass {
        // non-static nested class
    }
    static class StaticNestedClass {
        // static nested class
    }
}

Why Use Nested Classes?

Here are a few reasons:

  1. Logical Grouping: Keep helper classes inside the main class they belong to.

  2. Encapsulation: Hide details. An inner class can access private members of its outer class.

  3. Code Readability: Relevant code stays close together.


Inner Classes (Non-static Nested Classes)

Example

class Outer {
    private String message = "Hello";
    class Inner {
        void show() {
            System.out.println(message);
        }
    }
    void run() {
        Inner inner = new Inner();
        inner.show();
    }
}

Creating an Inner Class

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();

Types of Inner Class


Static Nested Classes

Example

class Outer {
    static String staticData = "Static Data";
    String instanceData = "Instance Data";
    static class StaticNested {
        void display(Outer outer) {
            System.out.println(staticData);
            System.out.println(outer.instanceData);
        }
    }
}

Creating a Static Nested Class

Outer outer = new Outer();
Outer.StaticNested nested = new Outer.StaticNested();
nested.display(outer);

Top-Level vs Nested Classes

Let’s compare access:

Class Type Access to Outer Instance Members
Inner Class ✅ Direct access
Static Nested ❌ Only through object reference
Top-Level Class ❌ Only through object reference

Shadowing in Nested Classes

Shadowing happens when multiple variables have the same name in different scopes.

Example

public class ShadowTest {
    int x = 0;
    class FirstLevel {
        int x = 1;
        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);                        // method param
            System.out.println("this.x = " + this.x);              // FirstLevel's x
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); // Outer x
        }
    }
}

Output

x = 23
this.x = 1
ShadowTest.this.x = 0

Summary

Feature Inner Class Static Nested Class
Tied to outer object ✅ Yes ❌ No
Access outer fields ✅ Directly ❌ Only statics directly
Can be static ❌ No ✅ Yes
Use case One object tightly depends on another Utility/helper grouping

When to use which type of nested class