In Kotlin, what is the difference between a class declared inside another class with no modifier versus one declared with the `inner` keyword?
answer
- No keyword = static-like nested
- inner keyword = holds outer reference
- Outer.Nested() vs outer.Inner()
- Kotlin default is opposite of Java
- Only inner can see outer's instance members
basics
~20 sBy 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 sA 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 linesclass 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
Knows that plain nesting is static-like and inner adds an outer reference, and can state the two construction syntaxes.
Explains why nested can't see outer members and recalls that Kotlin's default is the inverse of Java's.
Connects the default to memory-leak avoidance and reasons about when capturing the outer is actually desirable.
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