1. Overview
In this article, we will explain the Object declaration (old Java way) and package-level (new kotlin way) functions which are the equivalent of Java static methods and fields in Kotlin. As we all knew, Kotlin doesn’t have the static keyword.
2. Object Declaration for static members
A class is a template, and an object is an instance of a class. Usually, you define a class and then create multiple instances of that class wherever required. If you want to restrict the instantiation of an object to a single instance, then you can use the Object keyword in Kotlin to achieve a singleton object. It is equivalent to Java’s singleton pattern.
An object declaration is a singleton object that can be useful in several cases. This always results in a single instance even if two threads try to instantiate it. This makes it easier for us to declare the Singleton pattern in Kotlin. It is also like the static methods in Java.
object SingletonObject { fun validateCredentials(username: String, password: String) { // Code to validate credentials println("Validation completed") } } fun main() { SingletonObject.validateCredentials("John", "John123") }
You can force to generate the members of companion objects as real static methods and fields using @JvmStatic
annotation. You can use @JvmField for static fields.
object SingletonObject { @JvmField val TAG = "SingletonObject" @JvmStatic fun validateCredentials(username: String, password: String) { // Code to validate credentials println("Validation completed") } } fun main() { SingletonObject.validateCredentials("John", "John123") }
If you want to create a singleton object inside a class, then use the Companion object.
2.1 Companion Object
A companion object is a standalone object of the class that is an object declaration inside the class. If you want the class to access the private members of the singleton object, then you can use the Companion object.
If you need to call a function without using a class instance, then you can use the Companion object. Syntactically it is like the static methods in Java and you can access the companion object members using its class name as a qualifier.
class ExampleClass { val username = "John" companion object Named { fun create(): ExampleClass = ExampleClass() } } fun main() { val instance = ExampleClass.create() println(instance.username) }
In the above example, we are calling the create
function of the companion object using its class name ExampleClass
.
The name of the class used by itself acts as a reference to the companion object of the class. So here, ExampleClass
indeed refers to the companion object. Also ExampleClass
instance members can access the private members of the Companion object.
If you debug the code, you would see the ExampleClass
refers to companion object which is a singleton object.
The name of the companion object is optional so you can omit it if you don’t want it.
class ExampleClass { val username = "John" companion object { fun create(): ExampleClass = ExampleClass() } } fun main() { val instance = ExampleClass.create() println(instance.username) }
But you would call it in Java as below. The syntax is ClassName.CompanionObjectName.functionName (ExampleClass.CompanionName.create
).
class Caller { private String TAG = "Caller"; private String getUserName() { return ExampleClass.Named.create(); } }
If you don’t have any name for the companion object, then you would use ExampleClass.Companion.create
class Caller { private String TAG = "Caller"; private String getUserName() { return ExampleClass.Companion.create(); } }
2.1.1 Force Static using @JvmStatic
However, on the JVM you can force to generate the members of companion objects as real static methods and fields using @JvmStatic
annotation.
class ExampleClass { val username = "John" companion object CompanionName { @JvmField val TAG = "CompanionName" @JvmStatic fun create(): ExampleClass = ExampleClass() } }
2.1.2. Declare static variable in Kotlin
You can declare variables inside the Companion object or object declaration. Though you can access the variable using the class name, it is still a member of a singleton instance, and you can use @JvmField to force it real static fields.
class ExampleClass { companion object CompanionName { @JvmField val TAG = "CompanionName" } }
2.1.3. Passing Companion Object as a parameter.
You can pass the companion object as an argument to other methods as shown below.
fun main() { printUserName(ExampleClass) } fun printUserName(value: ExampleClass.CompanionName) { println(value.create().username) } class ExampleClass { val username = "John" companion object CompanionName { @JvmStatic fun create(): ExampleClass = ExampleClass() } }
3. package-level functions
It’s recommended to use package-level functions also known as top-level functions. You can declare functions and fields directly inside a file creating no class for them. They are often utility functions independent of any class.
Let’s take the same example.
package com.tedblob fun validateCredentials(username: String, password: String) { // Code to validate credentials println("Validation completed") } fun main() { validateCredentials("John", "John123") }
In this example, we declared the validateCredentials
static function outside any class and kept it directly as a top-level function.
4. Call java static method from kotlin
Static members of Java classes can be called using its class name followed by the member name just like in Java.
public class Student { public static String getStudentName() { return "Britto"; } } fun main() { println(Student.getStudentName()) }

Companion object can be passed as a parameter to function as mentioned in section 2.1.3 of this article, but we cannot pass this Student as a parameter to any function.
5. Conclusion
In this article, we have learned the equivalent of Java static methods and members in Kotlin. You can still refer to Kotlin docs for more insights.
If you would like to learn more on Kotlin, we recommend you to refer to our Kotlin articles.