Java Inner Classes
A class can be declared inside another class. This is useful when a small helper class only makes sense together with its outer class: a Node inside a linked list, a Builder inside the class it builds, an Entry inside a map. Java has four kinds of classes inside classes, and you will meet all of them in real code.
Static nested classes
A static nested class is like a normal class that just lives inside another one. You create it with Outer.Nested:
class Shop {
static class Item {
final String name;
final double price;
Item(String name, double price) {
this.name = name;
this.price = price;
}
}
static double total(Item... items) {
double sum = 0;
for (Item i : items) {
sum += i.price;
}
return sum;
}
}
public class Main {
public static void main(String[] args) {
Shop.Item tea = new Shop.Item("Tea", 120);
Shop.Item cup = new Shop.Item("Cup", 80);
System.out.println(Shop.total(tea, cup));
}
}200.0
The Item... parameter uses the varargs from Method Parameters.
Inner classes
A nested class without static is an inner class. Each inner object belongs to an outer object and can use its fields, even private ones:
class Counter {
private int count = 0;
class Clicker {
void click() {
count++;
System.out.println("Count is now " + count);
}
}
}
public class Main {
public static void main(String[] args) {
Counter c = new Counter();
Counter.Clicker a = c.new Clicker();
Counter.Clicker b = c.new Clicker();
a.click();
b.click();
a.click();
}
}Count is now 1 Count is now 2 Count is now 3
Both clickers belong to the same counter, so they increase the same count. The unusual c.new Clicker() says which outer object the inner one belongs to.
Local classes
A class can even be declared inside a method. It is then only usable in that method, and it can use the method's variables as long as they do not change:
public class Main {
public static void main(String[] args) {
String greeting = "Hi";
class Greeter {
String greet(String name) {
return greeting + ", " + name + "!";
}
}
Greeter g = new Greeter();
System.out.println(g.greet("Tara"));
System.out.println(g.greet("Dev"));
}
}Hi, Tara! Hi, Dev!
Anonymous classes
An anonymous class is a class without a name, declared and created in one expression. It is used for one-off implementations of an interface or an abstract class:
interface Discount {
double apply(double price);
}
public class Main {
public static void main(String[] args) {
Discount festival = new Discount() {
@Override
public double apply(double price) {
return price * 0.8;
}
};
System.out.println(festival.apply(1000));
}
}800.0
Because Discount has only one abstract method, the same thing can be written much more shortly with a lambda: Discount festival = price -> price * 0.8;. The Lambda topic shows how, and lambdas have replaced most anonymous classes in modern code.
Practice exercises
- Make a static nested class
Pointinside a classGeometryand a static method that returns the distance between two points. - Give a class
Playlista private list of song names and an inner classPlayerthat prints the next song. - Implement an interface
Shapewith an anonymous class whosearea()returns 42.