Java Inner Classes
A Java inner class is a class written inside another class. Inner classes help keep small helper classes close to the code that uses them.
Java uses the broader term nested class for any class declared inside another class. A non-static nested class is called an inner class, while a static nested class belongs to the outer class itself.
Member Inner Classes
A member inner class is declared inside another class, but outside any method. Each inner class object is connected to an object of the outer class, so it can access the outer object’s fields and methods, even when they are private.
class BankAccount {
private String owner;
private int balance;
BankAccount(String owner, int balance) {
this.owner = owner;
this.balance = balance;
}
class Statement {
void print() {
System.out.println(owner + " balance: $" + balance);
}
}
Statement createStatement() {
return new Statement();
}
}
public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount("Alice", 125);
BankAccount.Statement statement = account.createStatement();
statement.print();
}
}
Output:
Alice balance: $125
The Statement class is useful only with BankAccount, so it makes sense to define it inside BankAccount. The method print() reads owner and balance directly from the outer object.
Creating An Inner Class Object
Because a member inner class belongs to an outer object, you usually create it from an existing outer object. A helper method like createStatement() is often the clearest option for beginners.
You may also see the inline syntax account.new Statement(). It means: create a Statement object that is attached to the existing account object.
Static Nested Classes
A static nested class is declared with static. It does not need an outer object, and it cannot directly access non-static fields of the outer class.
Use a static nested class when the nested class is related to the outer class, but does not need data from a specific outer object.
class MathTools {
static class Doubler {
int apply(int number) {
return number * 2;
}
}
}
public class Main {
public static void main(String[] args) {
MathTools.Doubler doubler = new MathTools.Doubler();
System.out.println(doubler.apply(7));
}
}
Output:
14
The class name is written as MathTools.Doubler because Doubler is nested inside MathTools. No MathTools object is required.
Local And Anonymous Classes
A local class is declared inside a method. It is useful for a tiny helper class that is needed only inside that method.
An anonymous class is a class with no name. It is often used to create a quick implementation of an interface or abstract class. Anonymous classes are less common in modern Java than lambda expressions for simple functional interfaces, but they are still important to recognize.
interface Greeter {
void greet();
}
public class Main {
public static void main(String[] args) {
Greeter greeter = new Greeter() {
@Override
public void greet() {
System.out.println("Hello from an anonymous class.");
}
};
greeter.greet();
}
}
Output:
Hello from an anonymous class.
The expression new Greeter() { ... } creates an unnamed class that implements Greeter, then creates one object from that class.
When To Use Inner Classes
- Use a member inner class when a helper object needs access to one outer object.
- Use a static nested class when the helper class is strongly related to the outer class but does not need outer object data.
- Use a local or anonymous class for small, one-place behavior.
- Avoid inner classes when a normal separate class would be easier to read and reuse.
Common Mistakes
- Trying to create a member inner class without an outer object.
- Expecting a static nested class to access non-static outer fields directly.
- Using too many nested classes, which can make code harder to scan.
- Forgetting that an anonymous class ends with a semicolon after the closing brace.
Takeaway: inner classes let you group helper classes with the class or method that needs them, while static nested classes are related helpers that do not depend on an outer object.
