Advanced Java
Inner Classes & Lambdas
Complete lesson for Inner Classes & Lambdas using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with Java OOP and Collections where relevant.
Basics — Inner Classes & Lambdas
Section: Advanced Java. Inner, static nested, local, and anonymous classes — plus lambdas and method references.
Four nested types
- **Static nested class:** like a top-level class namespaced inside another. No hidden outer
this. Prefer this when you do not need the outer instance. - **Inner class (non-static):** holds
Outer.this.new Outer().new Inner(). - **Local class:** declared inside a method. Can see effectively final locals.
- **Anonymous class:**
new Interface() { ... }— one-off implementation. Lambdas replaced many of these.
| Type | Outer instance? | Typical use |
|---|---|---|
| Static nested | No | Builder, Entry, helpers |
| Inner | Yes | Iterator that walks outer fields |
| Local | If in instance method | Rare, named one-off |
| Anonymous | Same as local | Listeners (pre-lambda) |
Lambdas
- A lambda implements a **functional interface**:
(args) -> expressionor(args) -> { statements; }. - Captured local variables must be **final or effectively final** (not reassigned).
- Lambdas do not create a new named type you write, but they still compile to classes/methods behind the scenes (
invokedynamic).
import java.util.Arrays;
import java.util.List;
public class LambdaBasics {
public static void main(String[] args) {
List<String> names = Arrays.asList("neo", "ada", "linus");
names.sort((a, b) -> a.length() - b.length());
names.forEach(System.out::println);
}
} Method references
System.out::printlnisx -> System.out.println(x).- Kinds:
static(Integer::parseInt), instance on a target (list::add), instance on an unbound type (String::toLowerCase), constructor (ArrayList::new).
Advanced — Inner Classes & Lambdas
this, serialization, and when not to lambda
- Inside a lambda,
thisis the *enclosing* class, not the lambda. Inside an anonymous class,thisis the anonymous instance. - A non-static inner class cannot have static members (except compile-time constants) in older Java; Java 16 relaxed some static nested rules — interviews still say “inner class has a hidden outer reference”.
- Do not use a lambda if you need multiple methods, a meaningful
this, or a constructor. Use a named class. Comparator.comparing(User::name)plus.thenComparingis the Java 8+ sort idiom.
Tricky Interview Points
Q1) Inner class vs static nested class?
Answer Inner (non-static) holds a reference to the outer instance. Static nested does not and can be constructed without an outer object.
Q2) Why must captured locals be effectively final?
Answer The lambda may outlive the stack frame. Java copies the local; allowing reassignment would make the copy and the variable diverge.
Q3) Lambda vs anonymous class?
Answer Lambda is shorter, this is the outer class, and it targets a SAM. Anonymous class can implement many methods and declare state.
Q4) How do you instantiate an inner class from outside?
Answer new Outer().new Inner() — you need an outer instance.
Q5) What is a method reference?
Answer A compact lambda that only calls an existing method: Class::method or obj::method.
Q6) Can an interface have a lambda if it has default methods?
Answer Yes, as long as there is exactly one abstract method.
Simple Programs
Static nested class and a lambda filter
import java.util.ArrayList;
import java.util.List;
public class NestedDemo {
static class Pair {
final String key;
final int value;
Pair(String key, int value) {
this.key = key;
this.value = value;
}
}
public static void main(String[] args) {
List<Pair> pairs = new ArrayList<>();
pairs.add(new Pair("a", 1));
pairs.add(new Pair("b", 5));
pairs.removeIf(p -> p.value < 3);
pairs.forEach(p -> System.out.println(p.key + "=" + p.value));
}
} Problem Solving Tricks
- Default to static nested. Only make it inner when you truly need the outer instance.
- If a lambda is more than a few lines, extract a method and use a method reference.
- Do not shadow variables named
xjust to make(x) ->look clever — use domain names. removeIf,forEach,replaceAllon collections are the everyday lambda APIs.
Practice Programs List
- Write an inner
Iterator-style class that walks anint[]stored on the outer instance. - Convert that inner class to static nested by passing the array in.
- Sort a
Listwith a lambda and again withString::compareToIgnoreCase. - Show that reassigning a local used in a lambda is a compile error.
- Replace an anonymous
Runnablewith a lambda and then withthis::instanceMethod.