Skip to content

Lesson 07 · Nested & Inner Classes

Objectives

After this lesson you will be able to:

  • Distinguish static nested, inner (non-static), local, and anonymous classes.
  • Explain how each captures the enclosing instance and local variables.
  • Use the right nesting for the job.

The four kinds

KindDeclaredNeeds an outer instance?Can access outer instance members?
Static nestedas a static memberNoOnly static ones
Inner (non-static)as an instance memberYesYes, including private
Localinside a method(lives in that method)Yes (effectively final locals)
Anonymousinline expressionYes (effectively final locals)

Static nested vs inner

A static nested class is just a top-level class scoped inside another — no link to an outer object. An inner class holds an implicit reference to an enclosing instance, so it can read its private members.

java
class Outer {
    private int x = 10;
    static class Nested { int sum(int a, int b) { return a + b; } }   // no Outer needed
    class Inner { int readX() { return x; } }                        // uses Outer.this.x
}

Outer.Nested n = new Outer.Nested();          // no Outer instance
Outer.Inner i = new Outer().new Inner();      // needs an Outer instance

Exam trap

Creating an inner class needs an enclosing instance: the outer.new Inner() syntax. A static nested class is built with just new Outer.Nested(). An inner (non-static) class cannot declare static members (except static final constants).

Local and anonymous classes

A local class is declared inside a method; an anonymous class is a local class with no name, declared and instantiated in one expression — typically to implement an interface on the spot.

java
Runnable r = new Runnable() {        // anonymous class implementing Runnable
    @Override public void run() { System.out.println("hi"); }
};

interface Greeter { String greet(); }
Greeter g = () -> "hello";           // a lambda — lighter than an anonymous class

Gotcha

Local and anonymous classes may only capture local variables that are final or effectively final (never reassigned). Mutating a captured local — or trying to — is a compile error. They can freely read and mutate fields of the enclosing instance.

Beyond the exam

Lambdas (Module 06) replace most anonymous classes for functional interfaces, but anonymous classes are still needed when you must implement multiple methods or extend a class. A lambda has no this of its own — this refers to the enclosing instance, unlike an anonymous class.

Key Takeaways

  • Static nested: no outer instance (new Outer.Nested()); sees only static outer members.
  • Inner (non-static): bound to an enclosing instance (outer.new Inner()), sees its private members; can't hold non-constant static members.
  • Local/anonymous classes capture only effectively final locals; they may mutate enclosing fields.
  • An anonymous class implements/extends a type inline; a lambda is the lighter choice for a functional interface.

Lesson Quiz

Lesson Quiz · Nested & Inner Classes0 / 4
  1. How do you create an instance of a non-static inner class Inner of Outer?

    • Anew Outer.Inner()
    • Bnew Inner()
    • Cnew Outer().new Inner()
    • DOuter.new Inner()
  2. Which local variables can an anonymous class capture?

    • AAny
    • BOnly final or effectively final
    • COnly static
    • DNone
  3. A static nested class can access...

    • AAll outer members including private instance fields
    • BOnly static members of the outer class
    • CNothing from the outer class
    • DOnly public members
  4. Which CANNOT an inner (non-static) class declare?

    • AAn instance method
    • BA non-constant static field
    • CA constructor
    • DA field

Next: Pattern Matching. Run the matching code in labs/src/main/java/com/jse21/m03_oop/.