为什么Kotlin主函数需要@JVMStatic注解?

ncecgwcz  于 12个月前  发布在  Kotlin
关注(0)|答案(2)|浏览(126)

最近开始学习Kotlin。在Kotlin中声明main函数时,我注意到一个有趣的行为。即使在对象类中,它也使用@JvmStatic注解。我四处看了看,没有找到相关的帖子。

object Main {
    @JvmStatic
    fun main(args: Array<String>) {
        println("Hello World")
    }
}

为什么Kotlin中的main函数需要@JvmStatic注解?
由于我有Java和Scala的背景,这似乎是多余和不必要的,所以我很好奇Kotlin采用这种约定的背景和决策是什么。

wqsoz72f

wqsoz72f1#

如果你声明main为顶级函数,则@JvmStatic***不***必需。也就是说,如果你的Kotlin源文件的全部是:

fun main(args: Array<String>) {
    println("Hello World")
}

在这种情况下,您不需要@JvmStatic-所有顶级函数都被转换为Java中的静态方法,默认情况下称为XXXKt的类,其中XXX是您的Kotlin文件名。
注意,对于Kotlin中的无参数顶层main s,编译器实际上生成了一个合适的Java main,它接受String[] args,并委托给你的Kotlin函数。

// 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();
}

当你把main方法放在object中时,你需要@JvmStatic,因为object在Java中被转换为单例类。默认情况下,object中的所有成员都是非静态的。

object MyObject {
    fun main(args: Array<String>) {

    }
}

翻译成这样:

public final class MyObject {
    private MyObject() {}

    public static final MyObject INSTANCE = new MyObject();

    public void main(String[] args) { }
}

在Kotlin中执行MyObject.main(...)时,它实际上是Java中的MyObject.INSTANCE.main(...)。显然,这样的main方法不能用作Java程序的入口点,因为它不是静态的。

p3rjfoxz

p3rjfoxz2#

Kotlin没有直接等价的Java静态方法。最接近它的是顶级函数(不在任何类中)。为了在Java中调用这些方法,它们会自动编译为生成类中的Java静态方法,该类以文件命名,并附加“Kt”。
Kotlinobject在Java中没有直接的等价物。object是类的实际示例。它的函数只是常规的、非静态的方法。Kotlin对象可以通过Java中生成的INSTANCE静态字段访问。这只是返回Kotlin对象的类示例。通过它,你可以访问它的方法。
@JvmStatic告诉编译器将函数编译为静态函数。之所以没有自动完成,是因为它对函数施加了一系列限制,而这些限制通常在Kotlin中不存在,因此需要选择加入。例如,它不能引用或调用特定于类示例的任何东西,例如在其超类中定义的函数/属性,也不能重写任何东西。

相关问题