CodeToConcept
About

java

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

Sample Question

Think it through, then check the tutorial.

CodeToConcept

Quickly learn through simple, structured, and practical coding tutorials. Build your confidence from step zero to real-world experience.

© 2026 CodeToConcept. All rights reserved.

Quick Links

AboutTutorials

Tutorials

JavaHTMLCSS

Support

Privacy PolicyTerms of ServiceContact
GitHubTwitterYouTube

Java Inner Classes

Run each complete program separately. Its required helper classes and imports are included in the same code block. Short syntax fragments explain individual operations.

A class can be declared inside another class or within a method. Its location and modifiers decide whether it needs an outer object and which surrounding values it can use. We will compare member, local, anonymous, and static nested classes through those rules.

Inner classes allow us to logically group classes that are closely related. They can also access members of their enclosing class, including private members.

For example:

class Outer {
 
    private int number = 100;
 
    class Inner {
 
        void display() {
            System.out.println(number);
        }
    }
}

Here, Inner is declared inside Outer, so Inner is an inner class.

What Is an Inner Class?

A class declared inside another class is called a nested class.

When a nested class is not declared static, it is specifically called a non-static inner class.

Example

class Outer {
 
    class Inner {
 
    }
}

Here:

Outer
 └── Inner

Inner is a non-static inner class.

Java supports several forms of nested classes:

  1. Member inner class
  2. Static nested class
  3. Local inner class
  4. Anonymous inner class

Types of Nested and Inner Classes

Java's nested-class structure can be understood as:

Nested Classes
│
├── Static Nested Class
│
└── Inner Classes
    │
    ├── Member Inner Class
    ├── Local Inner Class
    └── Anonymous Inner Class

The important distinction is:

A non-static nested class is called an inner class.

1. Member Inner Class

A member inner class is a non-static class declared directly inside another class.

Example

class Outer {
 
    private int number = 100;
 
    class Inner {
 
        void display() {
            System.out.println(number);
        }
    }
}

Here, Inner is a member inner class.

Creating an Object of a Member Inner Class

A non-static inner class is associated with an instance of its outer class.

Example

class Outer {
 
    class Inner {
 
        void display() {
            System.out.println("Inside Inner class");
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        Outer.Inner inner = outer.new Inner();
 
        inner.display();
    }
}

Output

Inside Inner class

Notice the syntax:

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

The Inner object is created using an instance of Outer.

Why Is outer.new Inner() Required?

A non-static inner class is associated with an instance of its outer class.

Therefore:

Outer outer = new Outer();

creates the outer object.

Then:

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

creates an inner object associated with that outer object.

Conceptually:

Outer Object
     │
     └── Inner Object

Inner Class Accessing Outer Class Members

An inner class can directly access members of its enclosing class.

Example

class Outer {
 
    private String message = "Hello from Outer";
 
    class Inner {
 
        void display() {
 
            System.out.println(message);
        }
    }
}

Usage:

class Outer {
 
    private String message = "Hello from Outer";
 
    class Inner {
 
        void display() {
 
            System.out.println(message);
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        Outer.Inner inner = outer.new Inner();
 
        inner.display();
    }
}

Output

Hello from Outer

The message field is private, but the inner class can access it.

Inner Class Accessing Private Members

Inner classes have access to members of their enclosing class, including private members.

Example

class Employee {
 
    private String name = "John";
 
    class Details {
 
        void print() {
            System.out.println(name);
        }
    }
}

Usage:

class Employee {
 
    private String name = "John";
 
    class Details {
 
        void print() {
            System.out.println(name);
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Employee employee = new Employee();
 
        Employee.Details details =
                employee.new Details();
 
        details.print();
    }
}

Output

John

Outer Class Accessing Inner Class Members

The outer class can access members of its inner class through an inner-class object.

Example

class Outer {
 
    class Inner {
 
        private int number = 100;
    }
 
    void display() {
 
        Inner inner = new Inner();
 
        System.out.println(inner.number);
    }
}

Usage:

class Outer {
 
    class Inner {
 
        private int number = 100;
    }
 
    void display() {
 
        Inner inner = new Inner();
 
        System.out.println(inner.number);
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        outer.display();
    }
}

Output

100

The outer class can access the private member because the two classes are closely related and the Java language provides the required access.

Accessing Outer Class Members When Names Conflict

Sometimes an inner class and outer class have fields with the same name.

Example

class Outer {
 
    int number = 10;
 
    class Inner {
 
        int number = 20;
 
        void display() {
 
            System.out.println(number);
            System.out.println(this.number);
            System.out.println(Outer.this.number);
        }
    }
}

Usage:

class Outer {
 
    int number = 10;
 
    class Inner {
 
        int number = 20;
 
        void display() {
 
            System.out.println(number);
            System.out.println(this.number);
            System.out.println(Outer.this.number);
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        Outer.Inner inner = outer.new Inner();
 
        inner.display();
    }
}

Output

20
20
10

Explanation

number

refers to the nearest variable in scope.

this.number

refers to the current inner-class object's field.

Outer.this.number

refers to the field of the enclosing Outer object.

Outer.this

Outer.this is used to explicitly refer to the current object of the outer class.

Example

class Outer {
 
    String name = "Outer";
 
    class Inner {
 
        String name = "Inner";
 
        void display() {
 
            System.out.println(name);
            System.out.println(this.name);
            System.out.println(Outer.this.name);
        }
    }
}

Output:

Inner
Inner
Outer

This is particularly useful when both classes contain fields with the same name.

Multiple Inner Class Objects

Multiple inner objects can be associated with the same outer object.

Example

class Outer {
 
    class Inner {
 
        void display() {
            System.out.println("Inner object");
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        Outer.Inner first = outer.new Inner();
        Outer.Inner second = outer.new Inner();
 
        first.display();
        second.display();
    }
}

Output

Inner object
Inner object

Both inner objects are associated with the same outer instance.

Multiple Outer Objects

Different outer objects can have their own inner objects.

Example

class Outer {
 
    private int value;
 
    Outer(int value) {
        this.value = value;
    }
 
    class Inner {
 
        void display() {
            System.out.println(value);
        }
    }
}

Usage:

class Outer {
 
    private int value;
 
    Outer(int value) {
        this.value = value;
    }
 
    class Inner {
 
        void display() {
            System.out.println(value);
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer firstOuter = new Outer(100);
        Outer secondOuter = new Outer(200);
 
        Outer.Inner firstInner =
                firstOuter.new Inner();
 
        Outer.Inner secondInner =
                secondOuter.new Inner();
 
        firstInner.display();
        secondInner.display();
    }
}

Output

100
200

Each inner object is associated with its particular outer object.

2. Static Nested Class

A class declared with static inside another class is called a static nested class.

Example

class Outer {
 
    static class Nested {
 
        void display() {
            System.out.println("Static nested class");
        }
    }
}

Unlike a non-static inner class, a static nested class does not require an instance of the outer class.

Creating a Static Nested Class Object

class Outer {
 
    static class Nested {
 
        void display() {
            System.out.println("Static nested class");
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer.Nested nested =
                new Outer.Nested();
 
        nested.display();
    }
}

Output

Static nested class

Notice that we do not need:

Outer outer = new Outer();

Static Nested Class vs Inner Class

Compare:

Inner class

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

Static nested class

Outer.Nested nested =
        new Outer.Nested();

The key difference is the relationship with an outer object.

FeatureInner ClassStatic Nested Class
staticNoYes
Requires outer objectYesNo
Can directly access outer instance membersYesNo
Can access outer static membersYesYes
Object creationouter.new Inner()new Outer.Nested()

Static Nested Class Accessing Outer Members

A static nested class can directly access static members of the outer class.

Example

class Outer {
 
    static int number = 100;
 
    static class Nested {
 
        void display() {
 
            System.out.println(number);
        }
    }
}

Usage:

class Outer {
 
    static int number = 100;
 
    static class Nested {
 
        void display() {
 
            System.out.println(number);
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer.Nested nested =
                new Outer.Nested();
 
        nested.display();
    }
}

Output

100

Static Nested Class Cannot Directly Access Outer Instance Members

Consider:

class Outer {
 
    int number = 100;
 
    static class Nested {
 
        void display() {
 
            System.out.println(number);
        }
    }
}

This does not compile because number belongs to an instance of Outer, but the static nested class does not automatically have an outer instance.

To access it, an Outer object must be explicitly provided.

Example

class Outer {
 
    int number = 100;
 
    static class Nested {
 
        void display(Outer outer) {
 
            System.out.println(outer.number);
        }
    }
}

Usage:

Outer.Nested nested =
        new Outer.Nested();
 
nested.display(new Outer());

3. Local Inner Class

A local inner class is a class declared inside a method, constructor, or block.

Example

class Outer {
 
    void display() {
 
        class Local {
 
            void print() {
                System.out.println("Local inner class");
            }
        }
 
        Local local = new Local();
 
        local.print();
    }
}

Usage:

class Outer {
 
    void display() {
 
        class Local {
 
            void print() {
                System.out.println("Local inner class");
            }
        }
 
        Local local = new Local();
 
        local.print();
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        outer.display();
    }
}

Output

Local inner class

The Local class exists only within the scope where it is declared.

Local Inner Class Scope

Consider:

class Outer {
 
    void method() {
 
        class Local {
 
            void display() {
                System.out.println("Hello");
            }
        }
 
        Local local = new Local();
 
        local.display();
    }
}

Local is accessible inside method().

It cannot be directly referenced from another method:

void anotherMethod() {
 
    Local local; // Not accessible here
}

because the class is local to method().

Local Inner Class Accessing Local Variables

A local inner class can access local variables from the enclosing method if those variables are final or effectively final.

Example

class Outer {
 
    void display() {
 
        int number = 100;
 
        class Local {
 
            void print() {
 
                System.out.println(number);
            }
        }
 
        Local local = new Local();
 
        local.print();
    }
}

Output

100

number is effectively final because its value is not changed after initialization.

Effectively Final Variable

A variable is effectively final if it is not explicitly declared final but its value is never changed.

This is valid:

int number = 100;
 
class Local {
 
    void display() {
        System.out.println(number);
    }
}

This is not valid:

int number = 100;
 
number = 200;
 
class Local {
 
    void display() {
        System.out.println(number);
    }
}

The local variable is no longer effectively final.

You can explicitly use:

final int number = 100;

to make the intention clear.

Local Inner Class Accessing Instance Members

A local inner class can access members of its enclosing object.

Example

class Employee {
 
    private String name = "John";
 
    void display() {
 
        class Local {
 
            void print() {
 
                System.out.println(name);
            }
        }
 
        Local local = new Local();
 
        local.print();
    }
}

Output

John

4. Anonymous Inner Class

An anonymous inner class is a class without a name that is declared and instantiated at the same time.

Example

abstract class Animal {
 
    abstract void sound();
}

We can create an anonymous implementation:

abstract class Animal {
 
    abstract void sound();
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Animal animal = new Animal() {
 
            @Override
            void sound() {
 
                System.out.println("Dog barks");
            }
        };
 
        animal.sound();
    }
}

Output

Dog barks

There is no class name for the implementation.

Anonymous Inner Class with Interface

Anonymous inner classes are commonly used with interfaces.

Example

interface Greeting {
 
    void sayHello();
}

Implementation:

interface Greeting {
 
    void sayHello();
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Greeting greeting = new Greeting() {
 
            @Override
            public void sayHello() {
 
                System.out.println("Hello Java");
            }
        };
 
        greeting.sayHello();
    }
}

Output

Hello Java

Anonymous Inner Class with a Normal Class

An anonymous inner class can also extend a normal class.

Example

class Animal {
 
    void sound() {
        System.out.println("Animal sound");
    }
}

Usage:

class Animal {
 
    void sound() {
        System.out.println("Animal sound");
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Animal animal = new Animal() {
 
            @Override
            void sound() {
 
                System.out.println("Dog barks");
            }
        };
 
        animal.sound();
    }
}

Output

Dog barks

Anonymous Inner Class with Additional Methods

Consider:

Animal animal = new Animal() {
 
    @Override
    void sound() {
        System.out.println("Dog barks");
    }
 
    void run() {
        System.out.println("Dog runs");
    }
};

The run() method belongs to the anonymous class.

However, it is not accessible through the variable declared as Animal:

animal.run();

because the compile-time type of animal is Animal.

This is one reason anonymous classes are generally used for a small, focused implementation.

Anonymous Inner Class and Constructor Arguments

An anonymous class can call the constructor of its superclass.

Example

class Person {
 
    Person(String name) {
        System.out.println("Name: " + name);
    }
}

Usage:

Person person = new Person("John") {
 
    void display() {
        System.out.println("Anonymous class");
    }
};

The superclass constructor receives "John".

Anonymous Inner Class vs Lambda

For a functional interface:

interface Calculator {
 
    int add(int a, int b);
}

An anonymous class can be written as:

Calculator calculator = new Calculator() {
 
    @Override
    public int add(int a, int b) {
        return a + b;
    }
};

For a functional interface, a lambda is often more concise:

Calculator calculator =
        (a, b) -> a + b;

Important

Lambdas are not simply a shorter syntax for every anonymous inner class.

A lambda is specifically used with a functional interface, while an anonymous class can extend a class or implement an interface and can contain its own fields and methods.

Inner Class Implementing an Interface

A named inner class can implement an interface.

Example

class Outer {
 
    class Printer implements Runnable {
 
        @Override
        public void run() {
 
            System.out.println(
                    "Running inner class"
            );
        }
    }
}

Usage:

class Outer {
 
    class Printer implements Runnable {
 
        @Override
        public void run() {
 
            System.out.println(
                    "Running inner class"
            );
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        Outer.Printer printer =
                outer.new Printer();
 
        printer.run();
    }
}

Output

Running inner class

Nested Classes Inside Interfaces

Interfaces can contain nested types.

Example

interface Outer {
 
    class Helper {
 
        void display() {
            System.out.println("Helper");
        }
    }
}

The nested class is implicitly static when declared as a member of an interface.

Usage:

interface Outer {
 
    class Helper {
 
        void display() {
            System.out.println("Helper");
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer.Helper helper =
                new Outer.Helper();
 
        helper.display();
    }
}

Output

Helper

Inner Classes Inside Inner Classes

A nested class can itself contain another class.

Example

class Outer {
 
    class Inner {
 
        class DeepInner {
 
            void display() {
                System.out.println(
                        "Deep inner class"
                );
            }
        }
    }
}

Objects can be created like this:

class Outer {
 
    class Inner {
 
        class DeepInner {
 
            void display() {
                System.out.println(
                        "Deep inner class"
                );
            }
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Outer outer = new Outer();
 
        Outer.Inner inner =
                outer.new Inner();
 
        Outer.Inner.DeepInner deep =
                inner.new DeepInner();
 
        deep.display();
    }
}

Output

Deep inner class

Although possible, deeply nested structures can make code harder to understand, so they should be used only when they provide a clear design benefit.

Access Modifiers in Inner Classes

Member inner classes can use access modifiers such as:

public
protected
private

Example

class Outer {
 
    private class Inner {
 
        void display() {
            System.out.println("Private inner class");
        }
    }
}

A private inner class can be used only where its access rules permit.

Local and anonymous classes have different declaration rules because they are scoped within methods or expressions.

Inner Class and Inheritance

An inner class can extend another class.

Example

class Parent {
 
    void display() {
        System.out.println("Parent");
    }
}
 
class Outer {
 
    class Inner extends Parent {
 
        @Override
        void display() {
            System.out.println("Inner");
        }
    }
}

Usage:

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

Output

Inner

Inner Class and Encapsulation

Inner classes can be useful for encapsulation.

For example, an outer class can hide implementation details inside a private nested class.

class DataService {
 
    private class DataProcessor {
 
        void process() {
            System.out.println("Processing data");
        }
    }
 
    public void execute() {
 
        DataProcessor processor =
                new DataProcessor();
 
        processor.process();
    }
}

External code does not need to know about DataProcessor.

It only interacts with:

DataService

This can help keep implementation details hidden.

Practical Example: Iterator-Like Design

Suppose we have a simple collection class:

class NumberCollection {
 
    private int[] numbers = {10, 20, 30};
 
    class Printer {
 
        void print() {
 
            for (int number : numbers) {
 
                System.out.println(number);
            }
        }
    }
}

Usage:

class NumberCollection {
 
    private int[] numbers = {10, 20, 30};
 
    class Printer {
 
        void print() {
 
            for (int number : numbers) {
 
                System.out.println(number);
            }
        }
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        NumberCollection collection =
                new NumberCollection();
 
        NumberCollection.Printer printer =
                collection.new Printer();
 
        printer.print();
    }
}

Output

10
20
30

The inner class has direct access to the outer class's private state.

Practical Example: Event Handling

Anonymous inner classes were historically common in GUI event handling.

Example pattern:

Button button = new Button();
 
button.setListener(new Listener() {
 
    @Override
    public void onClick() {
 
        System.out.println("Button clicked");
    }
});

The anonymous class provides a small implementation specifically for that event.

Modern Java code may use lambdas when the listener is a functional interface.

Inner Class and Memory Relationship

A non-static inner class maintains an association with an instance of its enclosing class.

Conceptually:

Outer Object
     ↑
     │
Inner Object

Because of this relationship, a non-static inner class can access the outer instance's members.

A static nested class does not have this automatic enclosing-instance relationship.

This distinction can matter when designing long-lived objects because holding an inner-class object can keep its associated outer object reachable.

Member Inner Class vs Static Nested Class

FeatureMember Inner ClassStatic Nested Class
Declared with staticNoYes
Requires outer instanceYesNo
Has automatic outer-instance relationshipYesNo
Direct access to outer instance fieldsYesNo
Direct access to outer static membersYesYes
Creationouter.new Inner()new Outer.Nested()

Local Inner Class vs Anonymous Inner Class

FeatureLocal Inner ClassAnonymous Inner Class
Has a nameYesNo
Declared inside method/blockYesUsually inside an expression
Can define multiple methodsYesYes
Can be reused within its scopeYesUsually created for one use
Useful forLocal reusable logicOne-time implementation

Inner Class vs Static Nested Class

Consider:

class Outer {
 
    int value = 100;
 
    class Inner {
 
        void display() {
            System.out.println(value);
        }
    }
 
    static class Nested {
 
        void display() {
            // Cannot directly access value
        }
    }
}

The difference comes from whether the nested class has an enclosing outer object.

When Should You Use Inner Classes?

Inner classes can be useful when:

  • A helper class is meaningful only within one outer class.
  • The nested class needs access to the outer object's state.
  • You want to hide implementation details.
  • A small implementation is needed for a particular operation.
  • A class has a strong logical relationship with its enclosing class.

For example:

BankAccount
   └── Transaction

or:

Tree
   └── Node

The nested class can make that relationship explicit.

When Should You Avoid Inner Classes?

Avoid unnecessarily deep or complicated nesting.

For example:

Outer
 └── Inner
      └── Inner2
           └── Inner3

can make code difficult to maintain.

If the nested class represents an important independent concept, a top-level class may be clearer.

Common Mistakes

Mistake 1: Creating a Non-Static Inner Class Incorrectly

Incorrect:

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

Correct:

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

Mistake 2: Confusing Static Nested Classes with Inner Classes

Strictly speaking:

static class Nested

is a static nested class, not a non-static inner class.

The term "nested class" includes both.

Mistake 3: Accessing Instance Members from a Static Nested Class

This is invalid:

class Outer {
 
    int value = 100;
 
    static class Nested {
 
        void display() {
            System.out.println(value);
        }
    }
}

The static nested class does not automatically have an Outer instance.

Mistake 4: Modifying a Local Variable Captured by a Local Class

This is not allowed:

void method() {
 
    int value = 10;
 
    class Local {
 
        void display() {
            System.out.println(value);
        }
    }
 
    value = 20;
}

The local variable must be final or effectively final when accessed from the local class.

Mistake 5: Overusing Anonymous Classes

Anonymous classes are useful for small, focused implementations.

If the implementation becomes large, a named class may make the code easier to understand and maintain.

Important Syntax

Member inner class

class Outer {
 
    class Inner {
    }
}

Static nested class

class Outer {
 
    static class Nested {
    }
}

Local inner class

class Outer {
 
    void method() {
 
        class Local {
        }
    }
}

Anonymous inner class

Interface obj = new Interface() {
 
    @Override
    public void method() {
    }
};

Quick Comparison of All Types

TypeWhere DeclaredNameOuter Instance Required
Member inner classInside classYesYes
Static nested classInside classYesNo
Local inner classInside method/blockYesIt can access enclosing instance when applicable
Anonymous inner classInside expressionNoDepends on context

Frequently Asked Questions

What is an inner class?

An inner class is a non-static nested class declared inside another class.

How many types of inner/nested classes are there?

The commonly discussed types are:

  1. Member inner class
  2. Static nested class
  3. Local inner class
  4. Anonymous inner class

Strictly speaking, the static nested class is not an inner class because it is static.

Can an inner class access private members of the outer class?

Yes.

class Outer {
 
    private int value = 100;
 
    class Inner {
 
        void display() {
            System.out.println(value);
        }
    }
}

Can an inner class have static members?

Modern Java permits static members in nested classes, subject to the language rules for the particular kind of nested class and Java version. A static nested class can naturally contain static members.

Can an inner class extend another class?

Yes.

class Inner extends Parent {
}

Can an inner class implement an interface?

Yes.

class Inner implements Runnable {
}

Can an inner class be private?

Yes, a member inner class can have private access.

What is Outer.this?

Outer.this refers to the current instance of the enclosing outer class.

What is an anonymous inner class?

It is a class without a declared name that is defined and instantiated at the same time.

What is a static nested class?

A nested class declared with static. It does not require an instance of the outer class.

Key Points

  • A class declared inside another class is a nested class.
  • A non-static nested class is called an inner class.
  • Java supports member, local, and anonymous inner classes.
  • Java also supports static nested classes.
  • A member inner class requires an instance of its outer class.
  • Outer.this refers to the enclosing outer object.
  • Inner classes can access outer-class members, including private members.
  • Static nested classes do not require an outer-class object.
  • Static nested classes cannot directly access outer instance members.
  • Local inner classes are declared inside methods or blocks.
  • Local inner classes can access final or effectively final local variables.
  • Anonymous inner classes have no declared class name.
  • Anonymous classes are useful for one-time implementations.
  • Functional interfaces can often be implemented more concisely with lambdas.
  • Inner classes can help encapsulate closely related implementation details.
  • Deeply nested classes should be avoided when they make the design harder to understand.

Conclusion

Inner classes provide a way to keep closely related classes together and can be useful for encapsulation, organization, and localized behavior.

The overall structure can be remembered as:

Nested Classes
│
├── Static Nested Class
│
└── Inner Classes
    │
    ├── Member Inner Class
    ├── Local Inner Class
    └── Anonymous Inner Class

The most important difference is whether the nested class has an automatic relationship with an instance of the outer class:

Member Inner Class
        ↓
Requires Outer Object
 
Static Nested Class
        ↓
Does Not Require Outer Object
 
Local Inner Class
        ↓
Limited to Local Scope
 
Anonymous Inner Class
        ↓
One-Time Unnamed Implementation

Once these concepts are clear, you can understand how Java uses nested types for encapsulation, helper implementations, callbacks, event handling, and other object-oriented designs.

See you in next page....🙂

← GenericsJava Anonymous Class →
← GenericsJava Anonymous Class →