Discovering Kotlin: Companion objects – more than just a static replacement

Kotlin has been on the market for some time now, and since Android Studio 3.0 it is fully supported for Android Development. That is the reason why I decided to start only writing Kotlin whenever I could.

I’ve decided to make this blog series to show of what I’ve learned and found useful. If you want to learn Kotlin, or go from Java to Kotlin, it’s really easy and just looking through the official reference at kotlinlang.org is absolutely sufficient. So, I will not focus on teaching Kotlin, but rather the practical experiences solutions I’ve found nice and improvements I was not able to implement using Java.

The examples and code used may be Android oriented, but I’m sure the applications can be used on any platform.

The Companion Object

I have found the companion object to be amazing. It opens up a whole new way of thinking and writing code. So, what is it? Well, you’ll get the first introduction if you jump right into Kotlin and you want to write some static constants or functions. You’d find some post telling you that: “Kotlin simply puts all the static methods and values in companion objects “. So, it’s a way of gathering all the static accessors?

Wrong, wrong, wrong! Well it’s not wrong, however it’s not correct, it’s not JUST a way to gather the resources; it’s so much more! To explain it in detail I will need to go over some basic Kotlin regarding object.

Object

Instead of creating a class in Kotlin, you can choose to use the object declaration. This is a built-in shortcut that Kotlin has created to allow Singletons. So, by using object instead of class you will create a Singleton and you can call it by using the object name directly.

This object, or Singleton, is thread-safe and ready to use from start. See it as the environment instancing an object instead of you having to create an object instance from a class. It is possible to force the compiler to compile the actual singleton implementation into static values with @JvmStatic . But all your code is in Kotlin so that won’t be necessary, right?

Companion Objects are objects too

Just like the object-object, the companion object is a singleton created per class, if implemented. To create a companion object simply add it as an inner object. To access it just use the class name.

Practical Differences

So, what is the difference? You can create values and functions and access them through the class name. Well in this information alone, no information. But let’s say you have multiple classes extending some abstract class, and you have method that accepts those classes and wants to call the before mentioned values and functions. In Java you would have to start using reflection, generic methods for extracting methods and values and then cast the result etc. etc. It’s complicated and performance heavy. Not to mention that the classes would need to implement some static values and methods based on memory and your paradigm; remember static cannot be combined with abstract so there is no way to enforce implementation.

The Companion Object solves this on so many levels it’s amazing! Since the companion is an object you can easily pass it to a function, no reflection required. Do you want to call a similar method on different kind of arguments? No problem! The companion is an object remember, it can extend abstract classes and interfaces! Here is a working example of what’s possible.

In this example the companion is also used as a factory which is also a common use case. In this example I did not pass the companion objects into a function, but they are being returned in the when expression and being used right at the end of it.

In Android you start new activities (screens) by creating Intents filled with origin and destination information. This is a nice use case for the companion as well:

And there is also the new way to instantiate lifecycle aware view models

The examples I have shown are just a small extract of what I’ve found possible and they can be optimized further with abstract classes and interfaces for instance. I hope that companion objects are here to stay as they are powerful and clean, at least that’s my opinion. What do you think?