Nested classes in Java allow you to define a class within another class, promoting encapsulation and logical grouping. From static nested classes to anonymous inner classes, each type serves unique purposes. In this guide, you’ll learn how and when to use them, along with practical examples and best practices.
Table of Contents
What Are Nested Classes?
A nested class is a class declared inside another class. It’s used to:
- Group related classes.
- Enhance encapsulation.
- Improve code readability.
Java supports four types of nested classes:
- Static Nested Classes
- Non-Static (Inner) Classes
- Local Inner Classes (inside methods/blocks)
- Anonymous Inner Classes (no name)
1. Static Nested Classes
A static nested class is associated with the outer class but doesn’t require an instance of it.
Example:
public class University {
static class Student {
String name;
Student(String name) { this.name = name; }
}
public static void main(String[] args) {
// Instantiate without University object
Student student = new Student("Alice");
System.out.println(student.name); // Output: Alice
}
}
When to Use:
- For logical grouping of classes (e.g.,
University.Student
). - When the nested class doesn’t need access to outer class instance variables.
2. Non-Static Inner Classes
An inner class is tied to an instance of the outer class and can access its members.
Example:
public class LinkedList {
private Node head;
class Node { // Inner class
int data;
Node next;
Node(int data) {
this.data = data;
next = head;
head = this; // Access outer class field
}
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.new Node(10); // Instantiate via outer class instance
}
}
When to Use:
- When the nested class needs direct access to the outer class’s fields/methods.
- For helper classes (e.g.,
Node
inLinkedList
).
3. Local Inner Classes
A local inner class is defined within a method or block and is only accessible there.
Example:
public class Outer {
void display() {
class Local { // Local inner class
void print() { System.out.println("Local class"); }
}
Local local = new Local();
local.print();
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.display(); // Output: Local class
}
}
When to Use:
- For one-off utilities inside a method.
4. Anonymous Inner Classes
An anonymous inner class has no name and is declared/instantiated in a single step. Often used for event listeners.
Example (Runnable Interface):
public class AnonymousDemo {
public static void main(String[] args) {
Runnable r = new Runnable() { // Anonymous class
@Override
public void run() {
System.out.println("Running!");
}
};
new Thread(r).start(); // Output: Running!
}
}
When to Use:
- For quick implementations of interfaces or abstract classes (e.g., GUI event handling).
Comparison of Nested Classes
Type | Access Outer Members | Static | Instantiation |
---|---|---|---|
Static Nested | ❌ No (unless static) | ✅ Yes | Outer.StaticNested obj = new Outer.StaticNested(); |
Inner (Non-Static) | ✅ Yes | ❌ No | Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); |
Local Inner | ✅ Yes (final vars) | ❌ No | Inside method/block only. |
Anonymous Inner | ✅ Yes (final vars) | ❌ No | Inline during object creation. |
Common Mistakes (and Fixes)
1. Instantiating Non-Static Inner Class Without Outer Instance
Error:
Outer.Inner inner = new Outer.Inner(); // Error
Fix:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
2. Accessing Non-Final Variables in Local/Anonymous Classes
Error:
void method() {
int count = 0;
Runnable r = () -> System.out.println(count++); // Error: count not final
}
Fix: Declare variables as final
or use effectively final variables.
Best Practices
- Prefer Static Nested Classes: Unless you need access to outer instance fields.
- Limit Anonymous Classes: Use lambdas for functional interfaces (Java 8+).
- Keep Local Classes Short: Avoid cluttering methods with long class definitions.
Conclusion
Nested and inner classes in Java enhance encapsulation and organization. By choosing the right type (static, inner, local, or anonymous), you’ll write cleaner, more modular code.
FAQs
Can a nested class be private
or protected
?
Yes. Use access modifiers to control visibility.
Can nested classes extend other classes?
Yes. They behave like regular classes but with access restrictions.
Why use inner classes over static nested classes?
When the nested class needs direct access to the outer class’s instance variables.