Java Nested Classes
A nested class is a class declared inside another class. An inner class is a nested class without the word static, and each inner object stays tied to one outer object.
An inner class reads the outer field
Display sits inside Counter without the word static, so Display is an inner class. Its show method reads the value field of the Counter object that built it.
public class Main {
public static void main(String[] args) {
Counter counter = new Counter();
Counter.Display display = counter.new Display();
display.show();
}
}
class Counter {
int value = 42;
class Display {
void show() {
System.out.println(value);
}
}
}A static nested class uses its own fields
Label carries the word static, so no Counter object is needed to build one. Its show method reads its own name field and the static unit field of Counter.
public class Main {
public static void main(String[] args) {
Counter.Label label = new Counter.Label("Count");
label.show();
}
}
class Counter {
static String unit = "items";
static class Label {
String name;
Label(String name) {
this.name = name;
}
void show() {
System.out.println(name + " in " + unit);
}
}
}Two outer objects give two inner values
Each Display object is built from a different Counter object. Each one prints the value of its own outer object.
public class Main {
public static void main(String[] args) {
Counter first = new Counter(10);
Counter second = new Counter(20);
Counter.Display firstDisplay = first.new Display();
Counter.Display secondDisplay = second.new Display();
firstDisplay.show();
secondDisplay.show();
}
}
class Counter {
int value;
Counter(int value) {
this.value = value;
}
class Display {
void show() {
System.out.println(value);
}
}
}Example
public class Main {
public static void main(String[] args) {
Order order = new Order("Ana", 35);
Order.Receipt receipt = order.new Receipt();
receipt.print();
Order.Stamp stamp = new Order.Stamp("PAID");
stamp.print();
}
}
class Order {
static String currency = "dollars";
String customer;
int total;
Order(String customer, int total) {
this.customer = customer;
this.total = total;
}
class Receipt {
void print() {
System.out.println(customer + " paid " + total);
}
}
static class Stamp {
String word;
Stamp(String word) {
this.word = word;
}
void print() {
System.out.println(word + " in " + currency);
}
}
}Key points
- An inner class reads the fields of its outer object directly.
- Use outer.new Inner() to build an inner object from its outer object.
- A static nested class has no outer object tied to it.
- A static nested class reads its own fields and the static fields of its outer class.
- A static nested class is built from the class name alone, with no outer object.
In this example, the Receipt object is built from the Order object for Ana, so it prints her name and her total. The Stamp object needs no Order object, and it prints its own word with the static currency field.
Note
An inner object keeps a hidden reference to its outer object, so it can reach that object at any time.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
An outer object named box holds an inner class named Lid. Which expression builds a Lid object tied to box?