Question or issue of Kotlin Programming:
There is no static keyword in Kotlin.
What is the best way to represent a static Java method in Kotlin?
How to solve this issue?
Solution no. 1:
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 companion
keyword:
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 @JvmStatic
annotation. 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).
Solution no. 2:
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.
Solution no. 3:
A. Old Java Way :
-
Declare a
companion object
to 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
.kt
file.fun foo() = println("Foo") val bar ="bar"
-
Use the
methods/variables
with their names. (After importing them)Use :
foo() // Outputs Foo println(bar) // Outputs bar
Solution no. 4:
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.
Solution no. 5:
This also worked for me
object Bell { @JvmStatic fun ring() { } }
from Kotlin
Bell.ring()
from Java
Bell.ring()
Solution no. 6:
object objectName { fun funName() { } }
Solution no. 7:
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.frybitsclass 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.frybitsclass 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: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
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 object classes
Kotlin
@file:JvmName(“KotlinClass”)//This provides a name for this file, so it’s not defaulted as [KotlinClassKt] in Java
package com.frybitsobject 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 = 2fun someOtherFunction() = “What is ‘INSTANCE’?”
}Java
package com.frybits;class JavaClass {
void someFunction() {
println(KotlinClass.foo); //Direct read of [foo] in [KotlinClass] singletonprintln(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);
}
}
Solution no. 8:
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 } } }
Solution no. 9:
There are 2 ways you can apply static in Kotlin
First make a companion object under class
For ex:
class Test{ companion object{ fun isCheck(a:Int):Boolean{ if(a==0) true else false } } }
you can call this function as
Test.Companion.isCheck(2)
Another way we can use is to make an object class
object Test{ fun isCheck(a:Int):Boolean{ if(a==0) true else false } }
Happy Coding!
Solution no. 10:
Simply you need to create a companion object and put the function in it
class UtilClass { companion object { // @JvmStatic fun repeatIt5Times(str: String): String = str.repeat(5) } }
To invoke the method from a kotlin class:
class KotlinClass{ fun main(args : Array) { UtilClass.repeatIt5Times("Hello") } }
or Using import
import Packagename.UtilClass.Companion.repeatIt5Times class KotlinClass{ fun main(args : Array) { repeatIt5Times("Hello") } }
To invoke the method from a java class:
class JavaClass{ public static void main(String [] args){ UtilClass.Companion.repeatIt5Times("Hello"); } }
or by adding @JvmStatic annotation to the method
class JavaClass{ public static void main(String [] args){ UtilClass.repeatIt5Times("Hello") } }
or both by adding @JvmStatic annotation to the method and making static import in java
import static Packagename.UtilClass.repeatIt5Times class JavaClass{ public static void main(String [] args){ repeatIt5Times("Hello") } }
Solution no. 11:
Kotlin has no any static keyword. You used that for java
class AppHelper { public static int getAge() { return 30; } }
and For Kotlin
class AppHelper { companion object { fun getAge() : Int = 30 } }
Call for Java
AppHelper.getAge();
Call for Kotlin
AppHelper.Companion.getAge();
I think its working perfectly.
Solution no. 12:
I would like to add something to above answers.
Yes, you can define functions in source code files(outside class). But it is better if you define static functions inside class using Companion Object because you can add more static functions by leveraging the Kotlin Extensions.
class MyClass { companion object { //define static functions here } } //Adding new static function fun MyClass.Companion.newStaticFunction() { // ... }
And you can call above defined function as you will call any function inside Companion Object.
Solution no. 13:
For Java:
public class Constants { public static final long MAX_CLICK_INTERVAL = 1000;}
Equivalent Kotlin code:
object Constants { const val MAX_CLICK_INTERVAL: Long = 1000}
So for the equivalent of Java static methods is object class in Kotlin.
Solution no. 14:
To make it short you could use “companion object” to get into Kotlin static world like :
companion object { const val TAG = "tHomeFragment" fun newInstance() = HomeFragment() }
and to make a constant field use “const val” as in the code.
but try to avoid the static classes as it is making difficulties in unit testing using Mockito!.
Solution no. 15:
For Android using a string from a single activity to all the necessary activity.
Just like static in java
public final static String TEA_NAME = "TEA_NAME";
Equivalent approach in Kotlin:
class MainActivity : AppCompatActivity() { companion object { const val TEA_NAME = "TEA_NAME" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
Another activity where value is needed:
val teaName = MainActivity.TEA_NAME
Solution no. 16:
The exact conversion of the java static method to kotlin equivalent would be like this. e.g. Here the util class has one static method which would be equivalent in both java and kotlin. The use of @JvmStatic is important.
Java code:
class Util{ public static String capitalize(String text){ return text.toUpperCase();} }
Kotlin code:
class Util { companion object { @JvmStatic fun capitalize(text:String): String { return text.toUpperCase() } } }
Solution no. 17:
except Michael Anderson’s answer, i have coding with other two way in my project.
First:
you can white all variable to one class.
created a kotlin file named Const
object Const { const val FIRST_NAME_1 = "just" const val LAST_NAME_1 = "YuMu" }
You can use it in kotlin and java code
Log.d("stackoverflow", Const.FIRST_NAME_1)
Second:
You can use Kotlin’s extension function
created a kotlin file named Ext, below code is the all code in Ext file
package pro.just.yumu /** * Created by lpf on 2020-03-18. */ const val FIRST_NAME = "just" const val LAST_NAME = "YuMu"
You can use it in kotlin code
Log.d("stackoverflow", FIRST_NAME)
You can use it in java code
Log.d("stackoverflow", ExtKt.FIRST_NAME);
Solution no. 18:
Write them directly to files.
In Java (ugly):
package xxx; class XxxUtils { public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); } }
In Kotlin:
@file:JvmName("XxxUtils") package xxx fun xxx(xxx: Xxx): Yyy = xxx.xxx()
Those two pieces of codes are equaled after compilation (even the compiled file name, the file:JvmName
is used to control the compiled file name, which should be put just before the package name declaration).
Solution no. 19:
You can achieve the static functionality in Kotlin by Companion Objects
- Adding companion to the object declaration allows for adding the
static functionality to an object even though the actual static
concept does not exist in Kotlin. - A companion object can access all members of the class too, including the private constructors.
- A companion object is initialized when the class is instantiated.
-
A companion object cannot be declared outside the class.
class MyClass{ companion object { val staticField = "This is an example of static field Object Decleration" fun getStaticFunction(): String { return "This is example of static function for Object Decleration" } } }
Members of the companion object can be called by using simply the class name as the qualifier:
Output:
MyClass.staticField // This is an example of static field Object Decleration MyClass.getStaticFunction() : // This is an example of static function for Object Decleration
Solution no. 20:
Use @JVMStatic
Annotation
companion object { // TODO: Rename and change types and number of parameters @JvmStatic fun newInstance(param1: String, param2: String) = EditProfileFragment().apply { arguments = Bundle().apply { putString(ARG_PARAM1, param1) putString(ARG_PARAM2, param2) } } }