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

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

为什么Kotlin中的Main函数需要@JvmStatic注释?

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

推荐答案

如果将main声明为顶级函数,则@JvmStatic是必需的102.也就是说,如果您的整个Kotlin源文件是:

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

在这种情况下,您不需要@JvmStatic--所有顶级函数都被转换为Java中的静态方法,默认情况下在一个名为XXXKt的类中,其中XXX是您的Kotlin文件名.

请注意,对于Kotlin中无参数的顶级main,编译器实际上会生成一个适当的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中时,do需要@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程序的入口点,因为它不是静态的.

Kotlin相关问答推荐

等待下一个值时暂停Kotlin Coroutine

KMP:未能添加cafe.adriel.voyager依赖项

如何创建一个空的kotlin工作?

在 Kotlin 中定义基于多态函数的泛型函数

Kotlin中用于调用常量名称的枚举类方法之间的区别

如何访问嵌套在另一个 map 中的 map 中的值(在 kotlin 中)

在 Kotlin 协程中切换 IO 和 UI 的正确方法是什么?

为什么在 Kotlin 中调用私有构造函数会导致错误为无法访问 是什么?

如何从 kotlin 中的数据类访问 val?

这是什么 Kotlin 类型:(String..String?)

Dagger 2 ContributesAndroidInjector 为模块提供活动

Koin Android:org.koin.error.NoBeanDefFoundException

在 Kotlin 中,当枚举类实现接口时,如何解决继承的声明冲突?

如何在 kotlin 的片段类中更改 ActionBar 标题?

ActivityOptions.makeSceneTransitionAnimation 在具有多个视图的 kotlin 中不起作用

将 @Component.Builder 与构造函数参数一起使用

如果我可以将 Flow 和 StateFlow 与生命周期范围 \ viewLifecycleOwner.lifecycleScope 一起使用,那么在 ViewModel 中使用 LiveData 有什么意义

Kotlin:sealed class cannot "contain" data classes?

(kotlin的Moshi)@Json vs@field:Json

Gradle:无法连接到 Windows 上的 Kotlin 守护程序