Recently started learning Kotlin. I noticed an interesting behaviour when declaring the main function in Kotlin. It uses a @JvmStatic annotation even when in an object class. I looked around and did not find a relevant post.
object Main {
@JvmStatic
fun main(args: Array<String>) {
println("Hello World")
}
}
Why does the main function in Kotlin require a @JvmStatic annotation?
Coming from a Java and Scala background, it seems redundant and unnecessary, so I am curious what the background context and decision making was that made Kotlin adopt this convention.
@JvmStatic
is not required if you declare main
as a top-level function. That is, if the entirety of your Kotlin source file is:
fun main(args: Array<String>) {
println("Hello World")
}
You do not need @JvmStatic
in this case - all top-level functions are translated to a static method in Java, in a class called XXXKt
by default, where XXX
is your Kotlin file name.
Note that for parameterless top-level main
s in Kotlin, the compiler actually generates a proper Java main
that takes String[] args
, and delegate to your Kotlin function.
// the Kotlin main gets converted to something like this...
public static void main$1() {
// your kotlin code here...
}
// A proper Java main generated by Kotlin
public static void main(String[] args) {
main$1();
}
You do need @JvmStatic
when you put the main
method inside an object
, because object
s are translated to a singleton class in Java. All the members in the object
are non-static by default.
object MyObject {
fun main(args: Array<String>) {
}
}
is translated to something like this:
public final class MyObject {
private MyObject() {}
public static final MyObject INSTANCE = new MyObject();
public void main(String[] args) { }
}
When you do MyObject.main(...)
in Kotlin, it is actually MyObject.INSTANCE.main(...)
in Java. Obviously, such a main
method cannot be used as the entry point of a Java program, because it is not static.