30

我需要default void在 Kotlin 接口中创建一个方法。我遇到了一个问题,提示说Usage of@JvmDefault只允许使用-Xjvm-defaultoption

我需要在哪里写这个Xjvm-default

4

5 回答 5

22

@Target([AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY]) 注释类JvmDefault

指定应为非抽象 Kotlin 接口成员生成 JVM 默认方法。

此注释的用法需要指定显式编译参数:要么-Xjvm-default=enable要么 -Xjvm-default=compatibility

使用-Xjvm-default=enable,只为每个方法生成接口中的默认@JvmDefault方法。在这种模式下,用 注释现有方法会破坏二进制兼容性,因为它会有效地从 类@JvmDefault中删除该方法。DefaultImpls

with -Xjvm-default=compatibility,除了默认的接口方法, DefaultImpls类中还会生成一个兼容性访问器,它通过合成访问器调用默认的接口方法。在这种模式下,注释现有方法 @JvmDefault是二进制兼容的,但会导致字节码中的方法更多。

从接口成员中删除此注释是两种模式中的二进制不兼容更改。

只能使用 JVM 目标字节码版本 1.8 ( -jvm-target 1.8) 或更高版本生成默认方法。

@JvmDefault方法被排除在接口委托之外。

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-default/index.html

如果您使用 gradle 则将此参数添加到 gradle 脚本

https://kotlinlang.org/docs/reference/using-gradle.html

例如将此添加到 gradle:

kotlinOptions {
    freeCompilerArgs = ['-Xjvm-default=compatibility']
}

否则,如果您使用 Kotlinc 命令行编译器-Xjvm-default=compatibility,请在命令行中的命令之后添加

于 2018-12-28T21:20:25.837 回答
14

自 Kotlin 1.4 以来的答案是:

tasks.withType(KotlinCompile::class).all {
    kotlinOptions {
        jvmTarget = "11"

        // For creation of default methods in interfaces
        freeCompilerArgs = listOf("-Xjvm-default=all")
    }
}

然后你甚至可以完全放弃@JvmDefault

参照。https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#default-methods-in-interfaces

于 2020-08-19T12:46:28.590 回答
8

在根目录build.gradle下添加以下代码

allprojects {
    //Support @JvmDefault
    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
        kotlinOptions {
            freeCompilerArgs = ['-Xjvm-default=enable'] //enable or compatibility
            jvmTarget = "1.8"
    }
}
于 2019-12-06T09:36:18.220 回答
1

关于这个问题@JvmDefault似乎与这个问题很相似。

-Xjvm-default=enable标志必须传递给编译器。由于我假设您不kotlinc直接在命令行上使用(Kotlin 编译器):此问答包含有关在使用 Gradle 时如何将标志传递给 Kotlin 编译器的信息。

于 2018-12-29T01:17:25.647 回答
0

其他相关的故障输出可以是:is not abstract and does not override abstract method.

关于传递-Xjvm-default标志:

行家

kotlin-maven-pluginconfiguration的插件节点中添加

<args>
  <arg>-Xjvm-default=all</arg>
</args>

主意

在首选项中(通过dev.to):构建、执行、部署 -> 编译器 -> Kotlin 编译器 ->附加命令行参数添加-Xjvm-default=all

在项目结构中:模块 -> Kotlin ->附加命令行参数添加-Xjvm-default=all

@JvmDefault对于 kotlin > 1.4 应该不是必需的,但可能存在特殊的星座,手册应帮助确定需要哪种注释和标志组合。

于 2020-09-28T09:22:04.633 回答