What is the equivalent of Java static methods in Kotlin?
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).
How do you make Kotlin static variables and functions for Java?
You can't. Well, at least in a pure Kotlin project.
Kotlin has no notion of static
. The way static
works in a Kotlin-Java project is by use of annotations on the Kotlin classes to tell the JVM that the desired variable/function should be exposed as a static
to Java classes.
The following is an example guide for Kotlin-Java static
interop (answer originally posted in What is the equivalent of Java static methods in Kotlin?):
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);
}
}
This 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: 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
classesKotlin
// There is no more need for the @file:JvmName() annotation. The object class below already handles the proper naming.
//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);
}
}
Alternative way for kotlin static methods
One way to do this is by making the class open
or abstract
and adding this
companion object Default: Test()
This makes it act like every method of Test() is inside the companion object Default.
If you wanted, you could also override an open method and make it have a different output for when it is used statically:
fun main() {
val test = Test()
test.foo() //Output: "jiorgor"
Test.foo() //Output: "static jiorgor"
}
public open class Test() {
var giorgor: String = "jiorgor"
open fun foo() = println(giorgor)
companion object Default : Test() {
override fun foo() = println("static jiorgor")
}
}
Kotlin static methods and variables
The closest thing to Java's static fields is a companion object. You can find the documentation reference for them here: https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects
Your code in Kotlin would look something like this:
class Foo {
companion object {
lateinit var instance: Foo
}
init {
instance = this
}
}
If you want your fields/methods to be exposed as static to Java callers, you can apply the @JvmStatic
annotation:
class Foo {
companion object {
@JvmStatic lateinit var instance: Foo
}
init {
instance = this
}
}
Static methods in Kotlin as static method in Java
Works for me this way:
class C {
companion object {
@JvmStatic
fun foo(): Boolean = true
}
}
val method = C::class.java.getDeclaredMethod("foo")
Modifier.isStatic(method.modifiers) // true
Note that C::class.java
and C.javaClass
are different things: the former returns Class<C>
and the latter returns Class<C.Companion>
.
How to create static functions in Kotlin without creating an object
Unfortunately, there's currently no way to create a static function on a class in Kotlin that doesn't result in the instantiation of an Object (the companion object). You'll have to write it in Java and call it from Kotlin if you want to do this.
The @JvmStatic
annotation creates a static method in the JVM bytecode, but all that does is retrieve the instance of the companion object and call the method on it, which you can verify by decompiling the resulting bytecode.
use static Java methods as static (or singleton) properties in Kotlin
Having read the answers of the experts, having studied the links they provided, and having decompiled the Kotlin code of the wrapper class and analyzed a demo app (pure Java) which used the Kotlin-wrapped library, I decided to change the Java API.
Now I have a class with a public static object:
public class MyDevice {
public static MyDevice myDevice;
public void setLocation(Location location) {…}
public Location getLocation() {…}
}
now the Java consumers will use
import static com.example.sdk.MyDevice.myDevice;
Kotlin consumers don't need that static:
import com.example.sdk.MyDevice.myDevice
So, I don't need a separate Kotlin flavor of my library!
Possibility to call a Java static method in Kotlin
Yes, you can.
Java code:
public class MyJavaClass {
public static void printFoo() {
System.out.println("foo");
}
}
Kotlin code:
fun main(args: Array<String>) {
MyJavaClass.printFoo()
}
So easy =)
How to make static methods in Kotlin
In your java version the appComponent is static too. Might want to move appComponent to the companion object in the Kotlin version to make it static too.
Related Topics
How to Specify the Root Context in Your <Web-App> Tags in Web.Xml
Difference Between "Char" and "String" in Java
Comparing Strings by Their Alphabetical Order
How to Parse a JSON String to an Array Using Jackson
Is It Better Practice to Use String.Format Over String Concatenation in Java
Why We Shouldn't Make a Spring MVC Controller @Transactional
Loading a Text File into a Textarea
Selenium Webdriver: Wait for Complex Page with JavaScript to Load
Java: Text to Speech Engines Overview
Checking for Null - What Order
Spring Configure @Responsebody JSON Format
How to Stop Selenium from Creating Temporary Firefox Profiles Using Web Driver
Check and Extract a Number from a String in Java