Java Inner Classes
An inner class is a class written inside another class. Java uses inner classes when one class exists only to help another class. The helper stays close to its owner and stays out of the way of the rest of the program.
A Car Engine Example
A car contains an engine. The engine has no use outside the car in this design. Writing Engine inside Car shows that relationship and keeps the engine private to the car.
Diagram: Class Inside a Class
+--------------------------------+ | Outer: Car | | String model | | | | +------------------------+ | | | Inner: Engine | | | | int power | | | | start() | | | +------------------------+ | +--------------------------------+
Four Types of Inner Classes
| Type | Where It Lives |
|---|---|
| Member inner class | Inside the outer class body |
| Static nested class | Inside the outer class, marked static |
| Local class | Inside a method |
| Anonymous class | No name, created on the spot |
Member Inner Class
A member inner class needs an outer object. It can read every member of the outer class, even private ones.
class Car {
private String model = "Zen";
class Engine {
void start() {
System.out.println(model + " engine started");
}
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
Car.Engine engine = car.new Engine();
engine.start(); // Zen engine started
}
}
Static Nested Class
A static nested class needs no outer object. It cannot read non-static members of the outer class directly.
class School {
static class Library {
void open() {
System.out.println("Library open");
}
}
}
School.Library lib = new School.Library();
lib.open();
Local Class
A local class lives inside a method and works only there. Use it for small jobs that no other method needs.
void run() {
class Helper {
void say() {
System.out.println("Helping");
}
}
new Helper().say();
}
Anonymous Class
An anonymous class has no name. Developers create one to implement an interface or extend a class for a single use.
interface Greeting {
void hello();
}
Greeting g = new Greeting() {
public void hello() {
System.out.println("Hello from anonymous class");
}
};
g.hello();
Diagram: Who Needs an Outer Object
Member inner : needs Car object --> car.new Engine()
Static nested : needs nothing --> new School.Library()
Local : needs method call --> created inside run()
Anonymous : needs one-time use --> new Greeting() { ... }
Why Use Inner Classes
- Group helper classes with their owner
- Hide helper details from the rest of the program
- Reach private members of the outer class with ease
- Write short event handlers with anonymous classes
Common Mistakes
- Creating a member inner object without an outer object
- Reading a non-static outer member from a static nested class
- Building huge inner classes that deserve their own file
Real Example: A Bank Statement Printer
A bank account class keeps a list of transactions. A small inner class prints each line in a neat format. Only the account uses the printer, so the printer lives inside the account class.
class Account {
private double balance = 500;
class Printer {
void print() {
System.out.println("Balance: " + balance);
}
}
void showStatement() {
Printer p = new Printer();
p.print();
}
}
The Printer class reads the private balance field with no getter. The rest of the program never sees the Printer class at all.
Quick Summary
- Inner classes live inside other classes
- Java offers member, static nested, local, and anonymous types
- Member inner classes reach private outer members
