skip to content

Nested & Inner Classes

The four kinds of class you can declare inside another: static nested, inner, local and anonymous. Interviewers ask about them because the outer-instance reference is a real source of memory leaks.

part ofJavaoverview, primer and where to startread it →
on this pageshow

explore

questions

14

What is an inner (non-static) class in Java, and how does it differ from a static nested class?

level: juniorimportance: must knowfreq 72%

answer

  1. non-static = bound to an outer instance
  2. implicit hidden reference to outer
  3. can touch outer's private members
  4. static nested = no outer link, stands alone
  5. default to static; go inner only when state is needed

basics

~20 s

An inner class is a non-static class defined inside another class. Each inner-class object is tied to an object of the outer class and can use the outer object's fields and methods. A static nested class has no such tie.

solid answer

~40 s

An inner (non-static) class is a member class declared without the `static` keyword inside another class. Every inner-class instance is bound to a specific instance of the enclosing (outer) class, so it implicitly holds a reference to that outer object. Because of this binding, inner-class code can directly read and modify the outer instance's fields and call its methods, even private ones. You cannot create an inner-class instance without first having an outer instance. A static nested class, by contrast, carries no outer reference: it behaves like a top-level class that happens to live inside another for namespacing, and it can only touch the outer class's static members. Choose an inner class when the helper genuinely needs the outer object's state; otherwise prefer a static nested class.

go deeper

for a junior

Knows an inner class is non-static, lives inside another class, and can use the outer object's fields.

for a middle

Can clearly contrast inner vs static nested: the implicit outer reference, construction differences, and when to use each.

for a senior

Articulates the memory/leak consequence of the hidden outer reference and cites the default-to-static guidance with rationale.

for a principal

Frames the choice as an API/lifetime design decision (escaping references, GC retention, serialization pitfalls) and can reason about it across a codebase.

## Terms first - **Class**: a blueprint for objects. An **object** (or **instance**) is a concrete value created from a class with `new`. - **Nested class**: any class declared *inside* another class. Java has two broad kinds: **static nested classes** (declared `static`) and **inner classes** (declared *without* `static`). This question is about the non-static kind. - **Outer / enclosing class**: the class that physically contains the nested class. The nested class is sometimes called the **member class**. ## What makes an inner class special An **inner class** is a member class written without `static`. The defining rule: **every inner-class object belongs to one outer-class object.** When you create an inner-class instance, the runtime stores a hidden reference to a specific outer instance inside it. That hidden link is why inner-class code may freely use the outer object's members — including `private` ones — as if they were its own. A **static nested class** has no such hidden link. It is essentially a normal top-level class that the author chose to file *inside* another class for organization. It can only reach the outer class's `static` members, never per-instance fields, because it is not attached to any outer instance. ## Why the distinction matters 1. **Construction.** You can build a static nested class with `new Outer.Nested()`. You cannot build an inner class without an outer instance: `outerRef.new Inner()` (more on this syntax in a related question). 2. **Memory / lifetime.** Because an inner-class object pins the outer object alive (the hidden reference keeps it reachable for garbage collection), a long-lived inner instance can unintentionally keep a big outer object in memory — a classic leak. A static nested class has no such effect. 3. **State access.** Inner = needs the outer instance's data. Static nested = stands alone. ## A concrete mental model Think of `Map.Entry` versus an `Iterator` returned by a collection. An `Iterator` typically *is* an inner class: it must walk the very list instance that produced it, so it holds that list. A simple data-holder that does not depend on any particular outer object is a good static nested class. ## Rule of thumb Make a nested class `static` by default. Drop `static` (making it an inner class) **only** when it truly needs to read or mutate the enclosing instance's state. Effective Java explicitly recommends this, because a needless outer reference wastes memory and risks leaks.

  • Why does Effective Java recommend making a nested class static by default?
    A non-static inner class holds an implicit reference to its enclosing instance, costing memory and risking a leak that keeps the outer object alive. If the nested class does not need the outer instance, `static` avoids that reference entirely.
  • Can a static nested class access a private instance field of the outer class?
    No. It has no outer instance to read it from. It can only access the outer class's static members (and the instance members of an outer object explicitly passed to it).

An inner-class object is like a room that only exists as part of a specific house: it always knows which house it belongs to and can open that house's private cupboards. A static nested class is a portable shed — filed under the house's name, but it works fine on its own.

saying these in an interview costs you the question

  • Saying inner classes and static nested classes are the same thing
  • Claiming an inner class can be instantiated with plain `new Inner()` from outside the outer class
  • Thinking a static nested class can read per-instance outer fields

context

open as a page

What is a static nested class in Java, and how do you declare one?

level: juniorimportance: must knowfreq 70%

basics

~10 s

A static nested class is a class declared inside another class with the static keyword. You can create and use it without first creating an object of the outer class: new Outer.Nested().

open as a page

What does it mean that a local or anonymous class can only capture effectively-final local variables, and why does Java impose this rule?

level: middleimportance: must knowfreq 68%

basics

~20 s

A local variable used inside a local/anonymous class must never be reassigned after it's set — that's what 'effectively final' means. Java requires this because the class captures a copy of the variable's value, so allowing reassignment would let the two copies drift apart.

open as a page

What is the key difference between a static nested class and a (non-static) inner class regarding the enclosing instance?

level: middleimportance: must knowfreq 78%

basics

~20 s

A non-static inner class secretly holds a reference to the outer object that created it, so it can use the outer object's fields. A static nested class holds no such reference, so it can't reach the outer instance's fields and needs no outer object to be created.

open as a page

What is a local class and what is an anonymous class in Java, and how do they differ?

level: juniorimportance: should knowfreq 55%

basics

~20 s

A local class is a named class declared inside a method body. An anonymous class is a one-time, unnamed class you declare and instantiate in a single expression, usually to implement an interface or extend a class on the spot.

open as a page

How do you instantiate an inner (non-static) class from outside its enclosing class? Explain the outer.new Inner() syntax.

level: middleimportance: should knowfreq 55%

basics

~20 s

You first need an outer-class object, then create the inner object from it: Outer outer = new Outer(); Outer.Inner inner = outer.new Inner();. You can't write new Outer.Inner() because every inner instance needs an enclosing instance.

open as a page

How do you refer to the enclosing instance from inside an inner class, including when names collide? Explain OuterClass.this.

level: middleimportance: should knowfreq 58%

basics

~20 s

Inside an inner class, plain field names refer to the inner object first. To reach the outer object explicitly — for example when both have a field with the same name — write OuterClass.this.field or OuterClass.this.method().

open as a page

When you write an anonymous class with `new SomeType() { ... }`, how does the meaning differ depending on whether SomeType is a class or an interface, and what are the limits?

level: middleimportance: should knowfreq 50%

basics

~20 s

If SomeType is a class, the anonymous class extends it (a subclass) and the () calls that class's constructor. If SomeType is an interface, the anonymous class implements it and the () must be empty because interfaces have no constructor. Either way you get exactly one supertype.

open as a page

When a static nested class is compiled, what .class file is produced and how is it named?

level: middleimportance: should knowfreq 45%

basics

~10 s

Each nested class compiles to its own separate .class file. The name joins the outer and nested names with a dollar sign: Outer$Nested.class, alongside Outer.class.

open as a page

Why can a non-static inner class cause a memory leak, and how do you avoid it?

level: seniorimportance: should knowfreq 47%

basics

~20 s

An inner-class object secretly holds a reference to its outer object. If the inner object lives a long time (e.g., a listener or callback), it keeps the whole outer object alive in memory even after you're done with it. Use a static nested class to break that link.

open as a page

Inside an anonymous class, what does `this` refer to, and how do you reach the enclosing instance? How does this differ from a lambda?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Inside an anonymous (or local) class, this means that inner object itself, not the enclosing object. To reach the enclosing instance you write Outer.this. A lambda is different: its this is the enclosing instance, because a lambda has no this of its own.

open as a page

Given lambdas, method references, local classes, and anonymous classes, how do you decide which to use, and what are the trade-offs of each?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Use a lambda or method reference when you just need to fill in one method of a functional interface. Use an anonymous class when you must extend a class, implement multiple methods, or keep state. Use a named local class when you need a constructor or reuse it several times in the method.

open as a page

When should you reach for a static nested class instead of a top-level class, and what are real-world examples?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Use a static nested class when a helper type is only meaningful together with its outer class and you want to keep them grouped — for example a Builder inside the class it builds, or a Node inside a linked list. It scopes the helper without a separate top-level name.

open as a page

At the bytecode level, how does the JVM implement an inner class's access to the enclosing instance and its private members?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

The compiler turns an inner class into a separate top-level class file with a hidden field (often named this$0) holding the outer object. To let it read the outer's private members, older Java generated tiny synthetic accessor methods; modern Java (11+) uses nestmates so no extra methods are needed.

open as a page