skip to content

Inside an inner class, how do you access the outer class instance, and how do you disambiguate `this` when names collide between inner and outer?

level: middleimportance: must knowfreq 60%

answer

  1. this@Outer reaches enclosing instance
  2. Label is the class name after @
  3. Inner shadows same-named outer member
  4. Bare this == this@Inner
  5. Nested class: this@Outer won't compile

basics

~20 s

Use a labeled this: this@Outer refers to the outer object and this@Inner (or just this) to the inner one. This lets you pick the right object when both define a property or method with the same name.

solid answer

~30 s

An `inner` class can reach its enclosing instance through Kotlin's qualified-`this` syntax: `this@Outer`. Bare `this` (or `this@Inner`) is the inner instance. When the inner and outer both expose a member with the same name, the inner one shadows the outer, so you must write `[email protected]` to reach the outer's version. This qualified-`this` mechanism also works for outer labels of deeper nesting and for receivers of extension/lambda scopes. Nested (non-inner) classes have no enclosing-instance reference at all, so `this@Outer` is a compile error there. The label after `@` is the class name, not an arbitrary alias.

code

kotlin · 8 lines
kotlin
class Outer {
    val name = "outer"
    inner class Inner {
        val name = "inner"
        fun both() = "${[email protected]} + ${[email protected]}"
    }
}
fun main() = println(Outer().Inner().both()) // inner + outer

go deeper

for a junior

Knows this@Outer exists and that it reaches the enclosing object.

for a middle

Correctly resolves shadowing, uses the class-name label, and knows nested classes can't use it.

for a senior

Generalizes qualified-this to lambda/extension receivers and explains name-resolution precedence precisely.

for a principal

Articulates how lexical scoping plus qualified-this keeps receiver resolution unambiguous and how this scales to deeply nested DSL receivers.

## Qualified `this` Inside any class, bare `this` means 'the current instance'. In an `inner` class you sometimes need the **enclosing** instance instead. Kotlin provides **qualified this**: `this@ClassName`, where the label is the simple name of the enclosing class. ```kotlin class Outer { val name = "outer" inner class Inner { val name = "inner" fun describe(): String { val a = this.name // "inner" (same as [email protected]) val b = [email protected] // "inner" val c = [email protected] // "outer" return "$a/$b/$c" } } } // Outer().Inner().describe() -> "inner/inner/outer" ``` ## Shadowing The inner declaration `name` **shadows** the outer's `name`: an unqualified reference resolves to the closest scope, the inner. To reach the outer member you **must** qualify with `this@Outer`. Shadowing is purely a name-resolution rule; both members still exist. ## Only inner classes get an enclosing instance `this@Outer` is only valid where an enclosing instance exists — i.e. inside an `inner` class (or an object/lambda within an instance method). In a plain **nested** class there is no outer instance, so `this@Outer` does not compile. ## Labels beyond classes The same `this@Label` form disambiguates receivers in nested lambdas and extension scopes (e.g. `this@apply`, `this@run`), so the concept generalizes beyond inner classes. ## Key takeaways - `this@Outer` = enclosing instance; `this`/`this@Inner` = inner instance. - Same-named members: inner shadows outer; qualify to reach outer. - Nested (non-inner) classes cannot use `this@Outer`.

  • Does `this@Outer` work inside a non-inner nested class?
    No. A nested class has no enclosing instance, so the label is unresolved and it fails to compile.
  • Can the same label syntax be used in lambdas?
    Yes; receivers like `this@apply` or `this@run` use the identical qualified-this mechanism for nested receiver scopes.

saying these in an interview costs you the question

  • Claiming `this@Outer` works in a plain nested class
  • Thinking the label can be an arbitrary alias instead of the class name
  • Saying you can't reach a shadowed outer member at all
  • Believing bare `this` refers to the outer instance
  • Confusing qualified-this with reflection

context