library
intermediateInner Classes: Static, Member, Local, Anonymous
Know the four types of inner classes, when each is appropriate, and their relationship to the enclosing instance.
Four kinds of nested class, and the one difference that matters is whether it holds the enclosing instance.
Static nested = a tenant in an office building (uses the address but has their own key, doesn't need the landlord). Member inner = a personal assistant (always tied to a specific boss, has access to the boss's office).
Key Concepts
1
class Outer {
static class Nested { } // 1. no outer reference
class Member { } // 2. holds Outer.this2
void m() {
class Local { } // 3. inside a method
Runnable r = new Runnable() { // 4. anonymous
public void run() { }
};
}
}3
1. Static nested is a top-level class that happens to live inside another for naming. Map.Entry is the
familiar example. This is the default choice.
Map.Entry
4
2. Member inner holds a hidden reference to the outer object, which is how it reads outer fields
including private ones:
5
class Outer {
private int x = 1;
class Member { int get() { return x; } } // reaches Outer.this.x
}6
Outer.Member m = new Outer().new Member(); // needs an outer instance7
That hidden reference is a memory leak waiting to happen.
class Activity {
class Handler { } // holds the whole Activity8
void register() { registry.add(new Handler()); } // Activity now immortal
}9
The registry keeps the Handler, the Handler keeps the Activity, and nothing can be collected. Adding
static to Handler fixes it.
HandlerActivitystatic
10
3. Local is declared inside a method and can read effectively final locals. Rare now — a lambda does the
same job in a line.
11
4. Anonymous declares and instantiates in one expression. It was the standard way to write a callback
before Java 8:
12
list.sort(new Comparator<String>() {
public int compare(String a, String b) { return a.length() - b.length(); }
});13
list.sort(Comparator.comparingInt(String::length)); // today14
Anonymous classes still have their uses, because a lambda cannot extend a class or declare several
methods. An anonymous subclass can, and it also records its generic type — which is how TypeReference
works.
TypeReference
15
The rule: prefer static unless you genuinely need the enclosing instance.
static
16
What the interviewer is probing.1. "Why prefer a static nested class?" Probing: the memory leak. Stalls: "Style." *Moves
up:* a non-static inner class holds a hidden reference to the enclosing instance, so if the inner
object outlives the outer one, the outer cannot be collected.
17
2. "What can a local class capture from the enclosing method?" Probing: capture rules.
Stalls: "Everything." Moves up: only effectively final locals, because the captured value is
copied and the class may outlive the method frame.
18
3. "What does this refer to inside an anonymous class versus a lambda?" Probing: a real
behavioural difference when migrating. Stalls: "The same thing." Moves up: in an anonymous class
this is the anonymous instance; in a lambda it is the enclosing object.
19
4. "When is an anonymous class still the right choice over a lambda?" Probing: the limits of
lambdas. Stalls: "Never, lambdas replaced them." Moves up: when you need to extend a class,
implement several methods, or record a generic type as TypeReference does.