What are they?
A nested class is a class written inside another class. A nested class without static is called an inner class.
Nesting tells the reader that the two classes belong together. A second question is whether each nested object is tied to one outer object. The word static answers that.
Two common cases:
- Inner class (no
static). It belongs to one instance of the outer class and can use that outer object’s fields. You need an outer object to create it:outer.new Inner(). - Static nested class (declared with
static). It does not belong to an instance. It is only grouped with the outer class to keep code tidy. You create it without an outer object:OuterClass.NestedClass obj = new OuterClass.NestedClass(...).
When to use static nested
- When the nested class does not need the outer object (it never reads the outer’s non-static fields).
- When you want a singleton holder. The holder class is loaded once, so the one instance inside it is created once. Or when you want a builder that constructs the outer class.
Example: static nested class (Builder)
public class BurgerMeal {
private final String breadType;
private final String patty;
private BurgerMeal(BurgerMealWithBuilder builder) {
this.breadType = builder.breadType;
this.patty = builder.patty;
}
// Static nested: no outer instance needed. Name suggests it builds BurgerMeal.
public static class BurgerMealWithBuilder {
private String breadType;
private String patty;
public BurgerMealWithBuilder(String breadType, String patty) {
this.breadType = breadType;
this.patty = patty;
}
public BurgerMealWithBuilder withCheese(boolean add) {
// ...
return this;
}
public BurgerMeal build() {
return new BurgerMeal(this); // Allowed: a nested class can use its outer class's private members
}
}
}
// Usage: new BurgerMeal.BurgerMealWithBuilder("wheat", "chicken").withCheese(true).build()BurgerMealWithBuilderis static, so you can create it without aBurgerMealobject:new BurgerMeal.BurgerMealWithBuilder(...). This matters because theBurgerMealdoes not exist yet. The builder makes it.BurgerMeal’s constructor is private, so outside code cannot call it. Only the builder’sbuild()creates aBurgerMeal.
Example: static nested class (Singleton holder)
public class JudgeAnalytics {
private JudgeAnalytics() {}
// Holder: loaded only when first used; JVM guarantees thread-safe initialization
private static class JudgeAnalyticsHolder {
private static final JudgeAnalytics INSTANCE = new JudgeAnalytics();
}
public static JudgeAnalytics getInstance() {
return JudgeAnalyticsHolder.INSTANCE;
}
}- The holder is a static nested class. It exists only to hold the single
JudgeAnalyticsinstance. The holder is not loaded untilgetInstance()first uses it, so the instance is created lazily (only when first needed). Other code never namesJudgeAnalyticsHolder; it only callsgetInstance().
Where you see it in this repo
- BuilderPattern/After:
BurgerMeal.BurgerMealWithBuilderis the static nested builder. - SingletonDesignPattern/After:
JudgeAnalytics.JudgeAnalyticsHolderis the static nested holder for the singleton instance.