Nested classes

Nested classes in Kotlin behave a bit differently than in Java. A class defined within another class is not treated as an inner class by default, meaning it does not have an implicit reference to the enclosing class. In the following example, the Nested class cannot access Outer.a because it is not declared as an inner class using the inner keyword:

class Outer {
val a = "a"
val b = "b"

class Nested {
val c = a // error
}
}

If we look at the decompiled bytecode, we see that Nested is a static class, and therefore cannot access members of the enclosing class:

public final class Outer {
@NotNull
private final String a = "a";
@NotNull
private final String b = "b";

...

public static final class Nested {
@NotNull
private final String c = "c";

@NotNull
public final String getC() {
return this.c;
}
}
}

However, if we add the inner keyword to Nested, it will become a true inner class of Outer and will include a reference to the enclosing class:

class Outer {
val a = "a"
val b = "b"

inner class Nested {
val c = a // can now access Outer.a
}
}

In the following we can see the code generated by making the preceding change:

public final class Outer {
@NotNull
private final String a = "a";
@NotNull
private final String b = "b";

...

public final class Nested {
@NotNull
private final String c = Outer.this.getA();

@NotNull
public final String getC() {
return this.c;
}
}
}

If we look at the bytecode after adding the inner keyword, we can see that Nested is no longer static, and it can reference Outer.