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

问题描述 投票:0回答:2

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

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

为什么 Kotlin 中的 main 函数需要 @JvmStatic 注解?

来自 Java 和 Scala 的背景,这似乎是多余和不必要的,所以我很好奇 Kotlin 采用这种约定的背景和决策是什么。

java scala kotlin jvm compiler-construction
2个回答
0
投票
如果您将

@JvmStatic

 声明为顶级函数,则 
mainnot
 必需的。也就是说,如果您的整个 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();
}

当您将 @JvmStatic 方法放在

main
中时,您
do
需要
object
,因为
object
s 在 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程序的入口点,因为它不是静态的。


0
投票

Kotlin 没有直接等同于 Java 静态方法。最接近它的是顶级函数(不属于任何类的函数)。为了在 Java 中调用它们,它们会自动编译为生成的类中的 Java 静态方法,该类以附加“Kt”的文件命名。

Kotlin

object
s 在 Java 中没有直接的等价物。
object
是类的实际实例。它的功能只是常规的非静态方法。可以通过 Java 中生成的
INSTANCE
静态字段访问 Kotlin 对象。这只是返回 Kotlin 对象的类实例。通过它,你可以访问它的方法。

@JvmStatic
告诉编译器将函数编译为静态。这不是自动完成的原因是它对 Kotlin 中通常不存在的功能施加了一系列限制,因此有必要要求选择加入。例如,它不能引用或调用特定于类实例的任何东西,例如在其超类中定义的函数/属性,也不能覆盖任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.