skip to content

In Kotlin, what is the difference between a class declared inside another class with no modifier versus one declared with the `inner` keyword?

level: juniorimportance: must knowfreq 70%

answer

  1. No keyword = static-like nested
  2. inner keyword = holds outer reference
  3. Outer.Nested() vs outer.Inner()
  4. Kotlin default is opposite of Java
  5. Only inner can see outer's instance members

basics

~20 s

By default a class inside another class is nested and standalone: it does not know about the outer object. Adding the inner keyword links it to an outer instance, so it can use the outer object's data.

solid answer

~30 s

A class nested inside another with no modifier is a nested class. It is conceptually 'static': it holds no reference to an instance of the outer class and cannot access the outer's non-static (instance) members. You create it with `Outer.Nested()`. Marking it `inner` makes it an inner class: each instance carries an implicit reference to an enclosing `Outer` instance, so it can read the outer's instance properties/methods. You must create it from an outer instance: `outer.Inner()`. Kotlin defaults to nested (the opposite of Java, where inner is the default), which avoids accidental outer references and the memory leaks they cause.

code

kotlin · 9 lines
kotlin
class Outer {
    private val secret = 42
    class Nested { fun show() = "nested" }
    inner class Inner { fun show() = "secret=$secret" }
}
fun main() {
    println(Outer.Nested().show())   // nested
    println(Outer().Inner().show())  // secret=42
}

go deeper

for a junior

Knows that plain nesting is static-like and inner adds an outer reference, and can state the two construction syntaxes.

for a middle

Explains why nested can't see outer members and recalls that Kotlin's default is the inverse of Java's.

for a senior

Connects the default to memory-leak avoidance and reasons about when capturing the outer is actually desirable.

for a principal

Frames the default as a deliberate language design choice trading away Java compatibility for safer-by-default semantics, and weighs API/encapsulation implications.

## The two kinds Kotlin lets you declare a class inside another class. The modifier (or absence of one) controls whether it captures the enclosing object. - **Nested class** (no modifier): standalone. It does **not** hold a reference to an `Outer` instance and **cannot** touch the outer's instance members. Equivalent to a `static` nested class in Java. - **Inner class** (`inner` keyword): every instance holds an implicit reference to the `Outer` instance that created it, and can access the outer's instance members. ## Construction differs ```kotlin class Outer { private val secret = 42 class Nested { // static-like fun show() = "nested" // cannot see `secret` } inner class Inner { // holds Outer reference fun show() = "secret=$secret" // CAN see `secret` } } val n = Outer.Nested() // no Outer instance needed val i = Outer().Inner() // needs an Outer instance ``` ## Why Kotlin defaults to nested Java's default is the opposite: a non-`static` inner class captures the outer instance, which silently keeps it alive and is a classic source of memory leaks (e.g. an inner `Runnable` keeping an Activity alive on Android). Kotlin flips the default to the safer one: you only pay for an outer reference when you explicitly write `inner`. ## Key takeaways - No keyword = nested = no outer reference. - `inner` = captures outer instance, can use `this@Outer`. - Nested: `Outer.Nested()`; inner: `outerInstance.Inner()`.

  • If you forget `inner` and try to reference an outer instance property from the body, what happens?
    It does not compile: a nested class has no access to the outer's instance members, so the reference is unresolved.
  • Why is Kotlin's default safer than Java's?
    Java captures the outer instance by default, which can leak memory; Kotlin only captures when you opt in with `inner`.

A nested class is a tenant who shares the building's address but has no key to the landlord's apartment; an inner class is given that key.

saying these in an interview costs you the question

  • Saying nested classes can access outer instance members
  • Claiming you create a nested class via an outer instance like `outer.Nested()`
  • Stating Kotlin's default matches Java's (it is the opposite)
  • Confusing `inner` with `internal` (visibility)
  • Thinking `inner` is required for any nesting

context