Inner Class vs Nested Class in Kotlin
Inner Class vs Nested Class in Kotlin
Kotlin supports defining classes inside other classes, and the behavior depends on whether the inner keyword is used. A nested class (without inner) does not hold a reference to its enclosing class and behaves like a static inner class in Java. An inner class (with inner) holds an implicit reference to the enclosing class instance and can access its members directly. Understanding the distinction is important because it affects memory management, API design, and the risk of memory leaks in Android development. By the end of this lesson, you will be able to:
- Explain the difference between a nested class and an inner class in Kotlin.
- Describe how an inner class captures a reference to the enclosing instance.
- Identify memory leak risks when using inner classes in Android components.
- Apply the
this@OuterClasssyntax to reference the enclosing instance explicitly.
Nested Classes
A class declared inside another class without the inner keyword is a nested class. It cannot access the enclosing class's members because it does not hold a reference to any instance of the enclosing class:
class Outer {
val outerValue = "Outer"
class Nested {
fun show() = "No access to outerValue"
}
}
fun main() {
val nested = Outer.Nested()
println(nested.show()) // Output: No access to outerValue
}
Nested classes are instantiated without an instance of the enclosing class. You reference them using the outer class name directly: Outer.Nested(). In the compiled bytecode, a nested class is equivalent to a static inner class in Java. It has no implicit reference to the outer class, which means it does not contribute to memory retention of the outer instance.
Inner Classes
Adding the inner keyword to a class declared inside another class creates an inner class. An inner class holds an implicit reference to the enclosing class instance and can access all of its members, including private ones:
class Outer(val name: String) {
private val secret = "Secret Code"
inner class Inner {
fun reveal() = "Name: $name, Secret: $secret"
}
}
fun main() {
val outer = Outer("OuterName")
val inner = outer.Inner()
println(inner.reveal())
// Output: Name: OuterName, Secret: Secret Code
}
An inner class requires an instance of the enclosing class to be created. The syntax outer.Inner() makes this explicit. Internally, the compiler adds a constructor parameter for the outer class reference, and each inner class instance stores this reference for the duration of its lifetime.
This interview continues for subscribers
Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.
Become a Sponsor