In Kotlin, unlike Java, there is no concept of static members directly inside a class. Instead, Kotlin provides a special construct known as the companion object, which allows you to define members that belong to the class itself rather than any particular instance.
A companion object is a singleton object declared inside a class using the
companion object keyword. It allows you to define methods and properties that can be
accessed without creating an instance of the class, similar to static members in Java.
class Utils {
companion object {
fun printMessage(msg: String) {
println("Message: $msg")
}
}
}
fun main() {
// Accessing the function without creating an object
Utils.printMessage("Hello from Companion Object!")
}
In this example, the printMessage() function belongs to the class itself,
not to any specific instance. This means it can be accessed directly using the class name.
By default, the name of the companion object is Companion.
However, you can give it a custom name if needed:
class Config {
companion object Loader {
fun loadSettings() = "Settings loaded successfully!"
}
}
fun main() {
// Access via custom name
println(Config.Loader.loadSettings())
}
Even if you assign a name, you can still access the members directly using the class name
(Config.loadSettings()) because Kotlin automatically creates a reference for it.
object Database {
fun connect() = "Database connected"
}
class Server {
companion object {
fun start() = "Server started"
}
}
fun main() {
println(Database.connect()) // Standalone object
println(Server.start()) // Companion object
}
Companion objects are often used as factory methods to create instances of a class with controlled initialization logic.
class User private constructor(val name: String) {
companion object {
fun create(name: String): User {
println("User instance created")
return User(name)
}
}
}
fun main() {
val user = User.create("Talha")
println("Name: ${user.name}")
}
This approach encapsulates the object creation logic and hides the constructor, promoting clean and maintainable code.
static — it uses companion objects instead.
interface Provider {
fun provide(): String
}
class Service {
companion object : Provider {
override fun provide() = "Service Provided"
}
}
fun main() {
println(Service.provide())
}
This demonstrates that a companion object can implement interfaces, allowing flexible design and behavior.
The companion object in Kotlin is a powerful replacement for Java’s static members, providing flexibility and encapsulation. Whether for utility functions, constants, or factory methods, it’s a fundamental feature that promotes clean and object-oriented Kotlin code.