@JvmDefault和如何添加编译器选项

49

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

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


2
问题不清楚。请参见如何提出一个好问题 - coderpc
5个回答

51

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

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

使用此注解需要指定一个显式的编译参数:要么是-Xjvm-default=enable,要么是 -Xjvm-default=compatibility

当使用 -Xjvm-default=enable 时,对于每个带有 @JvmDefault 的方法,仅会在接口中生成一个默认方法。在这种模式下,为现有方法添加 @JvmDefault 注解可能会破坏二进制兼容性,因为它实际上将该方法从 DefaultImpls 类中删除。

当使用 -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

4
仅复制文档内容而不添加其他信息,可能对如何向编译器传递标志并不是非常有帮助。 - Markus Weninger
谢谢,但我从未收到答案...如何添加到参数中? - Evgesha
@Evgesha 如果你使用Gradle构建系统,请将其添加到Gradle构建脚本中 https://kotlinlang.org/docs/reference/using-gradle.html - ygngy
@Evgesha,我在我的答案中添加了对你问题的回答。 - ygngy
1
@kshetline 如果你打开 app 文件夹内的 build.gradle,你会看到一个 android { },把它放在 android{} 之间。 - ygngy
显示剩余3条评论

24

14
在根目录下的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"
    }
}

1
这个问题涉及到 @JvmDefault,看起来与 这个问题 相似。 -Xjvm-default=enable 标志必须传递给编译器。由于我假设您不直接在命令行上使用 kotlinc(Kotlin编译器):这个问答 包含有关如何在使用Gradle时向Kotlin编译器传递标志的信息。

1

其他相关的失败输出可能为:is not abstract and does not override abstract method

关于传递-Xjvm-default标志:

maven

在插件configuration节点中,添加kotlin-maven-plugin

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

IDEA

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

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

@JvmDefault 在kotlin > 1.4中不应该是必需的,但可能存在特殊情况,需要使用手册来确定所需的注释和标志的组合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接