Nested Classes in Java – Types, Rules and Examples
A nested class is a class declared inside another class. Java has four kinds: static nested classes, and three kinds of inner classes (non-static): member inner classes, local classes and anonymous classes. Nesting groups helper classes with the class they serve, strengthens encapsulation and can make code more readable.
This tutorial gives an overview of all four kinds in one runnable example, explains how nested classes access the outer class, and helps you choose the right one. Each kind has its own detailed tutorial.
1. Types of Nested Classes
| Kind | Declared | Needs outer instance? | Typical use |
|---|---|---|---|
| Static nested class | As a static member | No | Helpers, builders, node types (Map.Entry implementations) |
| Member inner class | As a non-static member | Yes | Objects tightly bound to one outer object (iterators) |
| Local class | Inside a method or block | Yes, if in an instance method | Helpers needed in only one method |
| Anonymous class | In an expression, without a name | Yes, if in an instance context | One-off implementations of interfaces or abstract classes |
2. All Four Kinds in One Example
import java.util.function.Supplier;
public class AllNestedKinds {
private String brand = "JavaByTechie";
private static int created = 0;
// 1. Static nested class: no outer instance needed
static class Counter {
int next() { return ++created; } // can use outer STATIC members
}
// 2. Member inner class: tied to an outer instance
class Badge {
String label() { return brand + " member"; } // can use outer INSTANCE members
}
Supplier<String> greeter(String name) {
// 3. Local class: declared inside a method
class Greeting implements Supplier<String> {
public String get() { return "Hello " + name + " from " + brand; }
}
return new Greeting();
}
Runnable announcer() {
// 4. Anonymous class: declared and instantiated in one expression
return new Runnable() {
@Override public void run() { System.out.println("Anonymous: welcome to " + brand); }
};
}
public static void main(String[] args) {
AllNestedKinds outer = new AllNestedKinds();
AllNestedKinds.Counter counter = new AllNestedKinds.Counter(); // no outer object
System.out.println("Static nested: " + counter.next() + ", " + counter.next());
AllNestedKinds.Badge badge = outer.new Badge(); // needs an outer object
System.out.println("Member inner: " + badge.label());
System.out.println("Local class: " + outer.greeter("Asha").get());
outer.announcer().run();
}
}
Static nested: 1, 2 Member inner: JavaByTechie member Local class: Hello Asha from JavaByTechie Anonymous: welcome to JavaByTechie
- A static nested class is created like any class:
new Outer.Nested(). - A member inner class object needs an outer object:
outer.new Inner(). - Local and anonymous classes can use the method's parameters and local variables if they are effectively final (
nameabove).
3. Access Between Outer and Nested Classes
A nested class and its outer class can access each other's private members. Since Java 11 they are formally nestmates, and the JVM grants this access directly:
public class PrivateAccess {
private int secret = 42;
class Inner {
private int innerSecret = 7;
int readOuter() { return secret; } // inner reads outer's private field
}
int readInner(Inner in) { return in.innerSecret; } // outer reads inner's private field
public static void main(String[] args) {
PrivateAccess outer = new PrivateAccess();
Inner in = outer.new Inner();
System.out.println("Inner reads outer private: " + in.readOuter());
System.out.println("Outer reads inner private: " + outer.readInner(in));
System.out.println("Compiled class name: " + Inner.class.getName());
System.out.println("Nestmates: " + PrivateAccess.class.isNestmateOf(Inner.class));
}
}
Inner reads outer private: 42 Outer reads inner private: 7 Compiled class name: PrivateAccess$Inner Nestmates: true
Each nested class compiles to its own .class file named Outer$Inner.class; anonymous classes get numbers, such as Outer$1.class.
4. Why Use Nested Classes?
- Logical grouping: a class used only by one other class lives next to it.
- Encapsulation: a private nested class is invisible outside, yet can access the outer class's private members.
- Readability: helper code is close to where it is used.
- Callbacks and event handlers can be written inline (although lambdas are now preferred for functional interfaces).
5. Choosing the Right Kind
- Does it need access to an outer instance? If not, use a static nested class. This is the default choice.
- Does it need the outer instance and is used in several methods? Use a member inner class.
- Is it needed in only one method, and does it need a name (for example, to create several instances)? Use a local class.
- Is it a single, short implementation? Use an anonymous class, or a lambda if the target is a functional interface.
6. Pitfalls
- Memory leaks: every inner class object holds a hidden reference to its outer object. A long-lived inner object (such as a listener or cached callback) keeps the outer object alive. Prefer static nested classes when the outer instance is not needed.
- Serialization: serializing inner classes is discouraged because of the hidden outer reference and compiler-generated fields.
- Shadowing: fields with the same name in inner and outer classes need
Outer.this.fieldto disambiguate.
7. Summary
- Nested classes are classes declared inside other classes.
- Static nested classes need no outer instance; inner classes (member, local, anonymous) do.
- Nested and outer classes can access each other's private members.
- Prefer static nested classes unless you need the outer instance; use lambdas for functional interfaces.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is a nested class in Java?
A class declared inside another class. It can be static (static nested class) or non-static (inner class).
Q2. What are the types of nested classes?
Static nested classes, member inner classes, local classes and anonymous classes.
Q3. What is the difference between a nested class and an inner class?
"Nested class" covers all classes declared inside another. "Inner class" means the non-static ones, which are tied to an outer instance.
Q4. Can an inner class access private members of the outer class?
Yes. All nested classes can access the outer class's private members, and the outer class can access theirs.
Q5. How do I create an object of a member inner class?
Through an outer object: Outer.Inner in = outer.new Inner();, or simply new Inner() inside an instance method of Outer.
Q6. How do I create an object of a static nested class?
Outer.Nested n = new Outer.Nested();. No outer object is needed.
Q7. Can a top-level class be static?
No. Only nested classes can be declared static.
Q8. Can inner classes have static members?
Since Java 16, yes. Earlier versions allowed only static constant fields in inner classes.
Q9. What is the class file name of a nested class?
Outer$Nested.class. Anonymous classes become Outer$1.class, Outer$2.class, and local classes Outer$1Local.class.
Q10. Why prefer static nested classes?
They do not hold a hidden reference to an outer object, which saves memory, avoids leaks and makes them independent and easier to reuse.
Q11. Can a nested class be private?
Yes. Member nested classes can have any access modifier, and private ones are visible only within the outer class.
Q12. What are nestmates?
A Java 11 JVM concept: a top-level class and its nested classes form a nest and can access each other's private members without synthetic accessor methods.
Q13. Can a nested class extend its outer class?
Yes. A nested class can extend any accessible, non-final class, including its outer class.
Q14. How do I access the outer object from an inner class?
Use OuterClassName.this, for example Outer.this.name.
Q15. Are lambdas a kind of nested class?
No. Lambdas are implemented differently (with invokedynamic) and do not create a new scope for this, but they often replace anonymous classes.
Q16. Can interfaces and enums be nested?
Yes. Nested interfaces, enums and records are implicitly static.
Q17. Can a nested class have a main method?
A static nested class can, and you run it with java Outer$Nested. Since Java 16 inner classes can declare static methods too.
Q18. Can inner classes cause memory leaks?
Yes. An inner object keeps its outer object reachable; if the inner object lives longer (for example, as a registered listener), the outer object cannot be garbage-collected.
Q19. Is a nested class loaded with its outer class?
No. Each nested class is a separate class loaded when first used. This is what makes the holder idiom for lazy singletons work.
Q20. How deep can classes be nested?
There is no fixed limit, but more than one level of nesting usually hurts readability.