What Is the Equivalent of Java Static Methods in Kotlin?
There Is No Static Keyword in Kotlin. What Is the Best Way to Represent a Static Java Method in Kotlin? 5 30 Answers You Place the Function in the "Companion...
There is no static keyword in Kotlin.
What is the best way to represent a static Java method in Kotlin?
30 Answers
You place the function in the "companion object".
So the java code like this:
class Foo {
public static int a() { return 1; }
}
will become
class Foo {
companion object {
fun a() : Int = 1
}
}
You can then use it from inside Kotlin code as
Foo.a();
But from within Java code, you would need to call it as
Foo.Companion.a();
(Which also works from within Kotlin.)
If you don't like having to specify the Companion bit you can either add a @JvmStatic annotation or name your companion class.
From the docs:
Companion Objects
An object declaration inside a class can be marked with the
companionkeyword:class MyClass { companion object Factory { fun create(): MyClass = MyClass() } }Members of the companion object can be called by using simply the class name as the qualifier:
val instance = MyClass.create()...
However, on the JVM you can have members of companion objects generated as real static methods and fields, if you use the
@JvmStaticannotation. See the Java interoperability section for more details.
Adding the @JvmStatic annotation looks like this
class Foo {
companion object {
@JvmStatic
fun a() : Int = 1;
}
}
and then it will exist as a real Java static function, accessible from
both Java and Kotlin as Foo.a().
If it is just disliked for the Companion name, then you can also
provide an explicit name for the companion object looks like this:
class Foo {
companion object Blah {
fun a() : Int = 1;
}
}
which will let you call it from Kotlin in the same way, but
from java like Foo.Blah.a() (which will also work in Kotlin).
Docs recommends to solve most of the needs for static functions with package-level functions. They are simply declared outside a class in a source code file. The package of a file can be specified at the beginning of a file with the package keyword.
Declaration
package foo
fun bar() = {}
Usage
import foo.bar
Alternatively
import foo.*
You can now call the function with:
bar()
or if you do not use the import keyword:
foo.bar()
If you do not specify the package the function will be accessible from the root.
If you only have experience with java, this might seem a little strange. The reason is that kotlin is not a strictly object-oriented language. You could say it supports methods outside of classes.
Edit: They have edited the documentation to no longer include the sentence about recommending package level functions. This is the original that was referred to above.
A. Old Java Way :
Declare a
companion objectto enclose a static method / variableclass Foo{ companion object { fun foo() = println("Foo") val bar ="bar" } }Use :
Foo.foo() // Outputs Foo println(Foo.bar) // Outputs bar
B. New Kotlin way
Declare directly on file without class on a
.ktfile.fun foo() = println("Foo") val bar ="bar"Use the
methods/variableswith their names. (After importing them)Use :
foo() // Outputs Foo println(bar) // Outputs bar
Use object to represent val/var/method to make static. You can use object instead of singleton class also. You can use companion if you wanted to make static inside of a class
object Abc{
fun sum(a: Int, b: Int): Int = a + b
}
If you need to call it from Java:
int z = Abc.INSTANCE.sum(x,y);
In Kotlin, ignore INSTANCE.
This also worked for me
object Bell {
@JvmStatic
fun ring() { }
}
from Kotlin
Bell.ring()
from Java
Bell.ring()
object objectName {
fun funName() {
}
}
Even though this is a bit over 2 years old now, and had plenty of great answers, I am seeing some other ways of getting "static" Kotlin fields are missing. Here is an example guide for Kotlin-Java static interop:
Scenario 1: Creating a static method in Kotlin for Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Java classes to treat this method as if it was a static to [KotlinClass] @JvmStatic fun foo(): Int = 1 //Without it, you would have to use [KotlinClass.Companion.bar()] to use this method. fun bar(): Int = 2 } }Java
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo()); //Prints "1" println(KotlinClass.Companion.bar()); //Prints "2". This is the only way to use [bar()] in Java. println(KotlinClass.Companion.foo()); //To show that [Companion] is still the holder of the function [foo()] } //Because I'm way to lazy to keep typing [System.out], but I still want this to be compilable. void println(Object o) { System.out.println(o); } }
Michael Anderson's answer provides more depth than this, and should definitely be referenced for this scenario.
This next scenario handles creating static fields in Kotlin so that Java doesn't have to keep calling KotlinClass.foo() for those cases where you don't want a static function.
Scenario 2: Creating a static variable in Kotlin for Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Kotlin to not generate the getter/setter functions in Java. Instead, this variable should be accessed directly //Also, this is similar to [@JvmStatic], in which it tells Java to treat this as a static variable to [KotlinClass]. @JvmField var foo: Int = 1 //If you want something akin to [final static], and the value is a primitive or a String, you can use the keyword [const] instead //No annotation is needed to make this a field of [KotlinClass]. If the declaration is a non-primitive/non-String, use @JvmField instead const val dog: Int = 1 //This will be treated as a member of the [Companion] object only. It generates the getter/setters for it. var bar: Int = 2 //We can still use [@JvmStatic] for 'var' variables, but it generates getter/setters as functions of KotlinClass //If we use 'val' instead, it only generates a getter function @JvmStatic var cat: Int = 9 } }Java
package com.frybits; class JavaClass { void someFunction() { //Example using @JvmField println(KotlinClass.foo); //Prints "1" KotlinClass.foo = 3; //Example using 'const val' println(KotlinClass.dog); //Prints "1". Notice the lack of a getter function //Example of not using either @JvmField, @JvmStatic, or 'const val' println(KotlinClass.Companion.getBar()); //Prints "2" KotlinClass.Companion.setBar(3); //The setter for [bar] //Example of using @JvmStatic instead of @JvmField println(KotlinClass.getCat()); KotlinClass.setCat(0); } void println(Object o) { System.out.println(o); } }
One of the great features about Kotlin is that you can create top level functions and variables. This makes it greate to create "classless" lists of constant fields and functions, which in turn can be used as static functions/fields in Java.
Scenario 3: Accessing top level fields and functions in Kotlin from Java
Kotlin
//In this example, the file name is "KSample.kt". If this annotation wasn't provided, all functions and fields would have to accessed //using the name [KSampleKt.foo()] to utilize them in Java. Make life easier for yourself, and name this something more simple @file:JvmName("KotlinUtils") package com.frybits //This can be called from Java as [KotlinUtils.TAG]. This is a final static variable const val TAG = "You're it!" //Since this is a top level variable and not part of a companion object, there's no need to annotate this as "static" to access in Java. //However, this can only be utilized using getter/setter functions var foo = 1 //This lets us use direct access now @JvmField var bar = 2 //Since this is calculated at runtime, it can't be a constant, but it is still a final static variable. Can't use "const" here. val GENERATED_VAL:Long = "123".toLong() //Again, no need for @JvmStatic, since this is not part of a companion object fun doSomethingAwesome() { println("Everything is awesome!") }Java
package com.frybits; class JavaClass { void someFunction() { println(KotlinUtils.TAG); //Example of printing [TAG] //Example of not using @JvmField. println(KotlinUtils.getFoo()); //Prints "1" KotlinUtils.setFoo(3); //Example using @JvmField println(KotlinUtils.bar); //Prints "2". Notice the lack of a getter function KotlinUtils.bar = 3; //Since this is a top level variable, no need for annotations to use this //But it looks awkward without the @JvmField println(KotlinUtils.getGENERATED_VAL()); //This is how accessing a top level function looks like KotlinUtils.doSomethingAwesome(); } void println(Object o) { System.out.println(o); } }
Another notable mention that can be used in Java as "static" fields are Kotlin object classes. These are zero parameter singleton classes that are instantiated lazily on first use. More information about them can be found here:
However, to access the singleton, a special INSTANCE object is created, which is just as cumbersome to deal with as Companion is. Here's how to use annotations to give it that clean static feel in Java:
Scenario 4: Using
objectclassesKotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits object KotlinClass { //No need for the 'class' keyword here. //Direct access to this variable const val foo: Int = 1 //Tells Java this can be accessed directly from [KotlinClass] @JvmStatic var cat: Int = 9 //Just a function that returns the class name @JvmStatic fun getCustomClassName(): String = this::class.java.simpleName + "boo!" //Getter/Setter access to this variable, but isn't accessible directly from [KotlinClass] var bar: Int = 2 fun someOtherFunction() = "What is 'INSTANCE'?" }Java
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo); //Direct read of [foo] in [KotlinClass] singleton println(KotlinClass.getCat()); //Getter of [cat] KotlinClass.setCat(0); //Setter of [cat] println(KotlinClass.getCustomClassName()); //Example of using a function of this 'object' class println(KotlinClass.INSTANCE.getBar()); //This is what the singleton would look like without using annotations KotlinClass.INSTANCE.setBar(23); println(KotlinClass.INSTANCE.someOtherFunction()); //Accessing a function in the object class without using annotations } void println(Object o) { System.out.println(o); } }
Kotlin has no any static keyword. You can use below code for Java and Kotlin
object AppHelper {
@JvmStatic
fun getAge() : Int = 30
}
Call for Java Class
AppHelper.getAge();
Call for Kotlin Class
AppHelper.getAge()
Its work perfectly for me. Thanks
You need to pass companion object for static method because kotlin don’t have static keyword - Members of the companion object can be called by using simply the class name as the qualifier:
package xxx
class ClassName {
companion object {
fun helloWord(str: String): String {
return stringValue
}
}
}
Top-level / companion object for static properties
Top-level
When the properties are somewhat related to a class, define them as top-level properties just before the class declaration:
const val MAX_ATTEMPTS = 3
private const val DEFAULT_NAME = "Guest"
private const val MIN_AGE = 16
data class User(val id: String, val name: String = DEFAULT_NAME)
This is similar to the static properties in Java.
When the properties are completely independent of any class, you can define them as top-level in a separate file without the class.
companion object
When the properties are closely related to a class and will be used only in that class, define them inside a companion object:
data class User(val id: String, val name: String = DEFAULT_NAME) {
companion object {
const val DEFAULT_NAME = "Guest"
const val MIN_AGE = 16
}
}