Bharatesh
Bharatesh

Reputation: 9009

Kotlin static functions : companion object, @JvmStatic @JvmField

I have just started messing around with the Kotlin programming language, which is pretty much cooler than Java. I have some doubts related to static methods and fields:

Q1: Official document says

Kotlin can also generate static methods for functions defined in named objects or companion objects if you annotate those functions as @JvmStatic.

But if you see below I can access bar() method as a static method, which works without using @JvmStatic annotation. But on official doc its throwing error -> Kotlin static method.

Class C{
    companion object{
        @JvmStatic
        fun foo() { }
        fun bar();
    }
}
fun main(args: Array<String>) {
    C.foo();
    C.bar(); //this line works fine
}

Q2: Do I really need @JvmStatic and @JvmField to make things static? As you can see with companion object, things are working as expected.

Upvotes: 14

Views: 7818

Answers (3)

hotkey
hotkey

Reputation: 147911

You can access members of a companion object as C.bar() in Kotlin, but not in Java. Without @JvmStatic, you would need to use C.Companion.bar() in Java, just as said in the docs.

Note that, without @JvmStatic, the function is compiled to an instance (non-static) method that is called on C.Companion in Java (and Kotlin simply shortens it to a call on C, but it's the same under the hood), so yes, you need either @JvmStatic and @JvmField to make a declaration in a companion object compile into a static member.

Basically, @JvmStatic and @JvmField are tools for Java interoperation that help with creating Java-friendly APIs, and if you don't need to call the Kotlin members from Java (e.g. they are internal to your Kotlin project, or you are developing a library that is unlikely to be used with Java), you can leave them as they are.

Upvotes: 21

hluhovskyi
hluhovskyi

Reputation: 10106

Yep, you do need @JvmStatic. The problem with your code that you call it in Kotlin while in documentation code was called in Java.

To be more precise, this code won't compile:

public void main(String[] args) {
    C.foo(); // Ok
    C.bar(); // Not ok
}

Kotlin knows about function in companion object so you can call it on class directly, while Java doesn't know anything about it. So you annotate any function with @JvmStatic and it becomes visible from Java code as static method.

And just to clarfiy - purpose of @JvmStatic is interop with Java code. If you write your application in Kotlin only you don't need @JvmStatic at all.

Upvotes: 2

Adrian K
Adrian K

Reputation: 4823

The documentation ("page 2") refers to the case where you call the function from Java, not Kotlin.

When you only use Kotlin, there is no need for the annotation. Instead use the way you declared your bar() method. So you can call C.bar()

Upvotes: -1

Related Questions