ProgramGuru

Objects, companions and nested classes

Objects, companions and nested classes

A school policy may be shared by the whole program rather than owned by each student instance. An object declaration defines a singleton under its initialization rules. A companion object groups members accessible through the containing class name.

What you’ll learn

  • Use shared policy and companion operations.
  • Distinguish singleton identity from safe mutation.

Objects, companions and nested classes in the example

  1. Shared policy

    A school policy may be shared by the whole program rather than owned by each student instance.

    Shared policy
  2. Companion operation

    A companion is an object, not simply a promise that every member maps to a Java static method.

    Companion operation
  3. Class-name access

    The companion function reads the shared constant and returns true for 80.

    Class-name access
The companion function reads the shared constant and returns true for 80. The next line prints 75 directly from the policy object. No Student instance is needed for this function call.

Understand objects, companions and nested classes

A companion is an object, not simply a promise that every member maps to a Java static method. JVM interop annotations can affect that mapping. A nested class does not hold an outer instance by default; an inner class explicitly does and can access its enclosing instance.

Follow objects, companions and nested classes

Save the complete source as Main.kt and use the Kotlin/JVM environment. No separate input file is needed.

Kotlin/JVM · complete program

object SchoolPolicy { const val passMark = 75 }
class Student(val score: Int) {
  companion object { fun passing(score: Int) = score >= SchoolPolicy.passMark }
}
fun main() {
  println(Student.passing(80))
  println(SchoolPolicy.passMark)
}

Expected output

true
75

Follow the execution

The companion function reads the shared constant and returns true for 80. The next line prints 75 directly from the policy object. No Student instance is needed for this function call.

Try this in the Kotlin compiler by pasting the complete program.

Practice: Objects, companions and nested classes

Your task: Does the policy object automatically make mutable shared state safe?

Kotlin/JVM · complete program

object SchoolPolicy { const val passMark = 75 }
class Student(val score: Int) {
  companion object { fun passing(score: Int) = score >= SchoolPolicy.passMark }
}
fun main() {
  println(Student.passing(80))
  println(SchoolPolicy.passMark)
}

Worked answer

No. A singleton can still hold mutable state that needs appropriate synchronization or confinement when accessed concurrently.

Objects, companions and nested classes: the important boundary

Keep global state limited and explicit. Object expressions create anonymous instances and differ from named singleton declarations. An inner class can extend the lifetime of its outer instance through the held reference.

Check your understanding

Does the policy object automatically make mutable shared state safe?
Choose one answer. You can try again.

Answer and explanation

No.

No. A singleton can still hold mutable state that needs appropriate synchronization or confinement when accessed concurrently.

Objects, companions and nested classes: what to keep in mind

No. A singleton can still hold mutable state that needs appropriate synchronization or confinement when accessed concurrently. Keep global state limited and explicit.

Further reading: official Kotlin documentation for this topic.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Generics and type constraints →