Solution:
The key difference between is that inner classes have full access to the fields and methods of the enclosing class. This can be convenient for event handlers, but comes at a cost: every instance of an inner class retains and requires a reference to its enclosing class.
With this cost in mind, there are many situations where we should prefer static nested classes. When instances of the nested class will outlive instances of the enclosing class, the nested class should be static to prevent memory leaks. Consider this implementation of the factory pattern:
public interface WidgetParser {
Widget parse(String str);
}
public class WidgetParserFactory {
public WidgetParserFactory(ParseConfig config) {
...
}
public WidgetParser create() {
new WidgetParserImpl(...);
}
private class WidgetParserImpl implements WidgetParser {
...
@Override public Widget parse(String str) {
...
}
}
}
At a glance, this design looks good: the WidgetParserFactory
hides the implementation details of the parser with the nested class WidgetParserImpl
. However, WidgetParserImpl
is not static, and so if WidgetParserFactory
is discarded immediately after the WidgetParser
is created, the factory will leak, along with all the references it holds.
WidgetParserImpl
should be made static, and if it needs access to any of WidgetParserFactory
’s internals, they should be passed into WidgetParserImpl
’s constructor instead. This also makes it easier to extract WidgetParserImpl
into a separate class should it outgrow its enclosing class.
Inner classes are also harder to construct via reflection due to their “hidden” reference to the enclosing class, and this reference can get sucked in during reflection-based serialization, which is probably not intended.
So we can see that the decision of whether to make a nested class static is important, and that one should aim to make nested classes static in cases where instances will “escape” the enclosing class or if reflection on those nested classes is involved.