skip to content

Both apply and also return the original object. When should you use apply versus also, and why?

level: middleimportance: must knowfreq 68%

answer

  1. apply = configure own members (this)
  2. also = side effect with it (log/validate/save)
  3. both return the same reference, inline
  4. also avoids this-shadowing when nested
  5. convention encodes intent, not capability

basics

~20 s

Use apply to set up an object's own properties (the object is 'this'). Use also for side actions like logging or checks that take the object as 'it'. Both hand the object back unchanged in identity.

solid answer

~40 s

apply and also share Axis 2 (both return the original object) but differ on Axis 1. apply exposes the object as the receiver this, so it reads as object configuration: you assign properties and call members without a qualifier — perfect for builder-style initialization (View().apply { ... }). also exposes the object as the argument it, so it reads as 'and also do this with it' — side effects that take the object as a parameter: logging, validation, registering, debugging in a chain. Rule of thumb: apply when the block's statements act ON the object's own members; also when the block hands the object TO something external (println(it), repository.save(it), require(it.valid)). Using also for config or apply for side effects technically works but obscures intent, which is the whole point of choosing.

code

kotlin · 4 lines
kotlin
val list = mutableListOf<String>()
    .apply { add("a"); add("b") }          // configure own state (this)
    .also { println("size now ${it.size}") } // side effect (it)
// list == [a, b]; the also block does not change it

go deeper

for a junior

Knows both return the original object and apply uses this, also uses it.

for a middle

Articulates the intent convention (config vs side effect) and picks correctly for a snippet.

for a senior

Cites the inline receiver-vs-parameter signatures and the this-shadowing argument for also when nesting.

for a principal

Turns this into a reviewable team convention and weighs it against builder DSLs / @DslMarker for larger config.

## Shared trait: identity-preserving return Both `apply` and `also` return the **exact same object reference** they were invoked on, discarding the lambda's result. Signatures: ```kotlin public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this } public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this } ``` Note `block: T.() -> Unit` (receiver, hence `this`) for `apply` vs `block: (T) -> Unit` (parameter, hence `it`) for `also`. Both are `inline`, so there's no lambda allocation overhead. ## `apply` — configure the object's own state Because the object is the receiver, you call members directly. This is the idiomatic Kotlin replacement for a separate builder when an object has mutable `var` properties or configuration methods: ```kotlin val paint = Paint().apply { color = Color.RED isAntiAlias = true strokeWidth = 4f } ``` Reads as: *take a Paint, set it up, give it back.* The statements operate on the object's own members. ## `also` — side effects with the object as an argument Because the object is `it`, the block naturally passes it to other functions: ```kotlin val saved = user .also { require(it.email.contains("@")) { "bad email" } } // validation .also { logger.info("saving {}", it) } // logging .let { repository.save(it) } ``` Reads as: *and also, with this object, do X (a side effect), then keep going.* `it` is renamable, which helps when the surrounding scope already has a meaningful `this`. ## Why the distinction matters Functionally you could swap them (rewrite `apply` config as `also { it.color = ... }`, or `also` logging as `apply { logger.info("{}", this) }`). But the **convention encodes intent**: - `apply` signals **object-internal configuration**. - `also` signals **external side effects / decoration** in a pipeline. Reviewers scan for these signals. A common team rule: *apply only assigns/configures; also only observes/decorates and never mutates the object's own properties.* ## Nesting and `this` clashes Inside a class or another receiver block, `apply`'s `this` can shadow the outer receiver, causing confusion about which `this` a bare member refers to. `also`'s explicit `it` avoids this and can be renamed (`also { node -> ... }`), making it the safer choice when scopes nest.

  • Can you rewrite an apply block as an also block?
    Yes, by qualifying every member with it (it.color = ...). It compiles but reads worse, so convention prefers apply for configuration.
  • Why is also often preferred inside class methods that already use this?
    also gives an explicit it you can rename, avoiding ambiguity with the enclosing this receiver.

apply is detailing a car you own (work on its own parts); also is the inspector who looks the car over and stamps a form, then waves it through.

saying these in an interview costs you the question

  • Saying apply and also return different objects
  • Using also to mutate the object's own properties as a habit
  • Claiming you cannot rename it in also
  • Thinking apply allocates a lambda (it's inline)
  • Believing one is faster than the other at runtime

context