
In this article, you’re going to learn what companion object
exactly is, how it behaves and what you can use it for in Kotlin!
Why you should use it?
The key to using companion object is that you treat it like a ‘companion’ of a given
class/interface . From a technical perspective, it’s a special object associated directly with a class instead of its instances, meaning no matter how many instances you create, there’ll always be only 1 companion object. It allows you to write more readable, performant, and maintainable code. You can use it for:
- Holding constants associated with a class
- Writing utility functions
- Sharing resources
- Creating factory methods
How does it work?
Example
Let’s work on an example so things are more straightforward. Here’s how you can define companion object
:
// It could be an interface as well class Example { companion object { const val TIMEOUT_MILLIS = 50 } }
In the case above, we have a nameless companion object
that’s associated with Example
class
. Inside it, you can write functions, define values and variables, etc., but remember that they’ll work like a Singleton.
Usage
class Example { fun timeout() { Thread.sleep(TIMEOUT_MILLIS) } companion object { const val TIMEOUT_MILLIS = 50 } } fun main() { Thread.sleep(Example.TIMEOUT_MILLIS) // Used outside }
So there’s an additional benefit: sometimes you’ll need a method that is associated with a given class but used outside of it as well and with companion object
you can do it.
What are the key characteristics?
- It’s public by default, but you can scope it to private
- Assigned only to a
class or
interface , we cannot assign it to an
object
as it does not apply to standalone objects (it’s not a class). - There can only be one
companion object per
class/interface
- Under the hood
companion object needs a name that’s Companion by default but can be easily changed, f.e
companion object YourName {...}
Additionally, it can access private members of a class — it sounds mysterious, but an example should clear things up:
class Example { private var age: Int = 0 companion object { fun updateAgeRandomly(example: Example) { example.age = Random.nextInt() println(example.age) } } }
Typically, you wouldn’t be able to access age
variable as it’s private, but companion object
can do so. However, in reality, it’s not as helpful because you can add a method to an Example
class, it’s worth noting that it’s possible and Extension functions
use the exact mechanism to access private fields of extended classes.
Job Offers
fun thanksForReading() { | |
if (learnedSomething) { | |
followForMoreContent() | |
clap() | |
} else { | |
commentHowToImprove() | |
} | |
} |
This article is previously published on proandroiddev.com.