skip to content

Object Expressions / Anonymous Objects

object : Type {} creates an anonymous instance on the spot, implementing an interface or extending a class while capturing surrounding variables. Interviewers contrast it with a lambda: an object expression can hold state and implement multiple members.

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

questions

5

What is a Kotlin object expression (anonymous object), and when would you use one instead of a named class?

level: juniorimportance: must knowfreq 70%

answer

  1. object : Type { } = anonymous instance at use site
  2. Expression -> new instance each evaluation
  3. Java anonymous inner class equivalent
  4. Can have no supertype (ad-hoc bundle)
  5. Extra members visible only for local/private use

basics

~20 s

An object expression creates a one-off, unnamed instance on the spot, often to implement an interface like a click listener. You use it when you need a single instance and don't want to write a whole named class.

solid answer

~40 s

An object expression is written `object : SomeType { ... }` and creates an anonymous instance that implements an interface or extends a class right where it is used. It is Kotlin's equivalent of a Java anonymous inner class. Use it for short, throwaway implementations, like passing a listener or comparator, where defining a named class would be overkill. The expression evaluates to an object you can assign to a variable, return, or pass as an argument. Unlike `object` declarations (singletons), an object expression is an expression evaluated each time the surrounding code runs, producing a fresh instance. It can override members and add new ones, and it can reference variables from the enclosing scope.

code

kotlin · 8 lines
kotlin
fun makeComparator(): Comparator<String> = object : Comparator<String> {
    override fun compare(a: String, b: String) = a.length - b.length
}

fun main() {
    val byLength = makeComparator()
    println(listOf("ccc", "a", "bb").sortedWith(byLength)) // [a, bb, ccc]
}

go deeper

for a junior

Knows the object : Type {} syntax and that it makes a quick one-off instance, e.g. a listener.

for a middle

Distinguishes expression vs declaration, knows a fresh instance is created each time, and that supertype is optional.

for a senior

Explains multiple supertypes, the no-supertype form, and the type-inference rule hiding extra members outside local/private scope.

for a principal

Frames when an anonymous object is the right tool vs a named class or object declaration, and weighs readability/maintenance trade-offs in API design.

## What it is An **object expression** creates an **anonymous object** — an instance of an unnamed class — at the point of use. The syntax is `object : Type { ... }`, which both declares an ad-hoc class and instantiates it in one step. It is the Kotlin counterpart to Java's anonymous inner class. ## Forms ```kotlin // 1. Implementing an interface val listener = object : Runnable { override fun run() = println("running") } // 2. Extending a class (pass constructor args after the type) open class Base(val id: Int) val b = object : Base(42) { override fun toString() = "Base#$id" } // 3. Object with NO supertype — just an ad-hoc bundle of members val point = object { val x = 1 val y = 2 } println(point.x + point.y) ``` ## Key facts - It is an **expression**: it evaluates to a value and runs each time control reaches it, producing a **new instance** every time. This contrasts with an `object` **declaration** (a singleton created once). - You may list **multiple supertypes** separated by commas: `object : A(), B { ... }` (one class at most, plus interfaces). - The anonymous object can **override** members and **declare new** ones. - **Type inference subtlety:** when the object has **no declared supertype**, the inferred type is the anonymous type and extra members are accessible only if it is used as a **local** or **private** member. If returned from a non-private function or stored in a non-private property, the visible type collapses to the supertype (or `Any` if none), hiding the extra members. ## When to use - Short, one-off implementations of an interface or abstract class (listeners, callbacks, `Comparator`, `Runnable`). - Building a small ad-hoc object with a few fields locally. For reusable behavior, prefer a named class; for stateless single-instance helpers, prefer an `object` declaration.

  • How does an object expression differ from an object declaration?
    A declaration (`object Foo { }`) is a named lazy singleton created once. An expression (`object : T { }`) is an unnamed value evaluated each time it runs, producing a fresh instance.
  • Can an object expression have no supertype at all?
    Yes: `object { val x = 1 }` is valid and produces an anonymous object whose only supertype is Any; its members are accessible when used as a local or private declaration.

Like sketching a custom tool on a napkin and handing it over once, instead of manufacturing a labeled product line.

saying these in an interview costs you the question

  • Confusing object expression with object declaration / singleton
  • Claiming it produces the same instance on every evaluation
  • Saying it must implement an interface (supertype is optional)
  • Thinking it cannot extend a class, only implement interfaces
  • Not knowing it is Kotlin's anonymous inner class equivalent

context

open as a page

How does a Kotlin object expression capture variables from its enclosing scope, and how does this differ from Java anonymous classes?

level: middleimportance: should knowfreq 55%

basics

~20 s

An anonymous object can read and use variables defined around it, like a local variable in the enclosing function. Unlike Java, those variables don't have to be final, and Kotlin even lets the object change them.

open as a page

What are the rules for supertypes in a Kotlin object expression, including supplying constructor arguments and combining multiple types?

level: middleimportance: should knowfreq 45%

basics

~10 s

After the colon you can list one class plus any number of interfaces, separated by commas. If the class has a constructor, you pass its arguments right after the class name, like calling it.

open as a page

Explain how the inferred type of an object expression with no declared supertype behaves when it leaks out of a function, and why extra members may become inaccessible.

level: seniorimportance: should knowfreq 35%

basics

~20 s

If an anonymous object has no named supertype, its special members are only usable nearby. Once you return it from a public function, the visible type drops to the supertype (or Any), so the extra members disappear from the caller's view.

open as a page

When should you reach for an object expression versus a lambda / SAM conversion when supplying an interface implementation in Kotlin?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Use a lambda when the interface has a single method and you only need that one method. Use an object expression when you must implement several methods, keep state, or override members of a class.

open as a page