When should you prefer a lambda over an anonymous inner class in Java, and when must you fall back to an anonymous class?
answer
- Lambda = functional interface (one abstract method)
- Anon class = multiple methods / fields / state
- Need a superclass (not interface)? anon class
- Need `this` = the implementor? anon class
- Lambda is terser + cleaner `this`
basics
~20 sUse a lambda when implementing a functional interface (one abstract method) — it is shorter and clearer. Use an anonymous class when you need state (fields), multiple methods, a constructor, or to implement an interface/class with more than one method.
solid answer
~40 sPrefer a lambda whenever the target is a *functional interface* — exactly one abstract method — because it is more concise, reads as intent, and avoids boilerplate. A lambda also gives you the cleaner `this` semantics (enclosing instance). Fall back to an anonymous class when the lambda form simply can't express what you need: you must implement an interface or abstract class with more than one abstract method, you need instance fields to hold state across method calls, you need an instance initializer or to override `equals`/`toString`, or you want `this` to mean the implementing object itself. Anonymous classes are also still required when subclassing a concrete class. In short: lambda for single-method behaviour, anonymous class for anything needing a richer object shape.
go deeper
Knows lambdas are for single-method interfaces and that anonymous classes are needed for 'bigger' implementations.
Lists the concrete blockers (multiple abstract methods, extending a class, fields/state, self-this) that force an anonymous class.
Weighs readability, this semantics, and runtime representation when choosing, and brings in method references as the terser alternative.
Sets team conventions: prefer lambdas/method references for behaviour, reserve anonymous/named classes for stateful or multi-method shapes, and explains the trade-offs to others.
## Terms - **Functional interface**: an interface with exactly one *abstract* method (it may have default/static methods too). Examples: `Runnable`, `Comparator<T>`, `Callable<V>`. Only these can be the target type of a lambda. - **Lambda**: shorthand for an instance of a functional interface — just the parameter list and body. - **Anonymous inner class**: a one-off, unnamed class defined and instantiated inline; can implement *any* interface or extend *any* (non-final) class, with as many methods and fields as you like. ## When a lambda is the right choice Use a lambda when **all** of these hold: 1. The target type is a **functional interface** (single abstract method). 2. You only need to supply that one method's behaviour. 3. You don't need extra instance state, multiple methods, or the implementing object's own `this`. Benefits: less boilerplate, clearer intent (`names.sort(comparing(String::length))`), better `this` semantics (refers to the enclosing object), and lighter runtime representation (no per-lambda class file at compile time). ## When you MUST use an anonymous class A lambda physically cannot express these, so reach for an anonymous class when you need to: - **Implement an interface with more than one abstract method** — a lambda fills exactly one method. - **Extend a class** (abstract or concrete) rather than implement a functional interface — lambdas only target interfaces. - **Hold instance state** in fields that persist across calls to the method. - **Provide a constructor body / instance initializer block**, or override `Object` methods like `equals`, `hashCode`, `toString`. - **Refer to the implementing object via `this`** (e.g. to register/unregister itself as a listener), since a lambda's `this` is the enclosing object. ```java // Lambda: single-method functional interface button.addActionListener(e -> System.out.println("clicked")); // Anonymous class: needs its own state + self-reference button.addActionListener(new ActionListener() { private int clicks = 0; // state across invocations public void actionPerformed(ActionEvent e) { clicks++; if (clicks == 3) button.removeActionListener(this); // 'this' = the listener } }); ``` ## Rule of thumb Default to the **lambda** for single-method behaviour; switch to an **anonymous class** only when you need a richer object — multiple/extra methods, persistent fields, a superclass, overridden `Object` methods, or a self-`this`. Method references (`String::length`) are an even terser alternative when the lambda just forwards to an existing method.
- Can a lambda implement an interface that has two abstract methods?No. A lambda targets a functional interface, which by definition has exactly one abstract method. With two abstract methods you must use an anonymous class or a named class.
- You need a listener that removes itself after firing. Lambda or anonymous class, and why?An anonymous class, because it needs `this` to mean the listener object so it can call `removeListener(this)`. In a lambda, `this` is the enclosing instance, not the listener.
saying these in an interview costs you the question
- Claiming a lambda can implement an interface with two abstract methods
- Saying lambdas can extend a class (they only target interfaces)
- Believing a lambda can keep instance fields/state like an anonymous class
- Thinking anonymous classes are always obsolete — they're still required for richer shapes