DEV Community

Bigyan Thapa
Bigyan Thapa

Posted on • Edited on

Kotlin Object Vs Companion Object

Recently I came across a question during a code-review. It was in the context of a PR where kotlin class and a bunch of functions inside a companion object {} annotated as @JvmStatic for Java interoperability were used. The feedback was "why we can't convert the class into an object and get rid of the companion object {}?".This raised the question, "what is the benefit with that?". Some explanation was done, but I wasn't completely satisfied with the explanation given (by me :)). So, decided to do a bit reading and document the differences, and use-cases for my future reference and for someone who will stumble upon similar question.

Object

Object in kotlin is a way of implementing Singletons. We all have come across the need of Singleton pattern in our career for various use-cases. Well, in kotlin this has been made very straight forward.
e.g.

object MyObject {
  // further implementation
  fun printHello() {
    println("Hello World!")
  }
}

This implementation is also called object declaration. Object declarations are thread-safe and are lazy initialized, i.e. objects are initialized when they are accessed for the first time.

Companion Object

If we want some implementation to be a class but still want to expose some behavior as static behavior, companion object come to the play. These are object declarations inside a class. These companion objects are initialized when the containing class is resolved, similar to static methods and variables in java world.
e.g.

class MyClass {

  // some implementations

  companion object {
    val SOME_STATIC_VARIABLE = "some_static_variable"
    fun someStaticFunction() {
      // static function implementation
    }
  }
}

Summary

Given the above explanation, the use-case completely depends on the problem we are trying to solve. If we need to provide the Singleton behavior, then we are better off with Objects, else if we just want to add some static essence to our classes, we can use Companion objects.

Bonus - Accessing Objects & Companions from Java

@JvmField, lateinit, const, @JvmStatic are handy when it comes to accessing field properties or functions defined in objects or companion objects.
e.g. our object can be something like below

object MyObject {

  @JvmStatic
  fun printStaticHello() {
    println("Static Hello World!")
  }

  fun printNonStaticHello() {
    println("Non-Static Hello World!")
  }
}

From Java world, we can access those functions as:

MyObject.printStaticHello() OR
MyObject.INSTANCE.printNonStaticHello() - this uses the singleton instance

e.g. accessing companion object

class MyClass {

  companion object {
    @JvmStatic
    fun printStaticHello() {
      println("Static Hello World!")
    }

    fun printNonStaticHello() {
      println("Non-Static Hello World!")
    }
  }
}

From Java world, we can access those as:

MyClass.printStaticHello()
MyClass.Companion.printStaticHello()
MyClass.Companion.printNonStaticHello()

Thank you for reading.
Note: Further reading and references, here & here

Top comments (3)

Collapse
 
nameisjayant profile image
Jayant Kumar

love it

Collapse
 
bigyan4424 profile image
Bigyan Thapa

Thank you!

Collapse
 
unaluzdev profile image
Luz Cucarella

Thank you! I tend to forget about singletons, so often confuse objects and companion objects. Very well explained 😄