【问题标题】:@JvmDefault and how add compiler option@JvmDefault 以及如何添加编译器选项
【发布时间】:2019-05-26 14:43:07
【问题描述】:

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

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

【问题讨论】:

标签: kotlin compiler-flags kotlinc jvm-default


【解决方案1】:

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

指定应该为 非抽象 Kotlin 接口成员。

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

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

-Xjvm-default=compatibility,除了默认界面 方法中,会生成一个兼容性访问器 DefaultImpls 类,通过 a 调用默认接口方法 合成访问器。在这种模式下,用 @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

【讨论】:

  • 在没有附加信息的情况下复制文档文本很可能对如何将标志传递给编译器没有太大帮助。
  • 谢谢,但我一直没有收到答复...如何添加参数?
  • @Evgesha 如果你使用 gradle build system 将它添加到 gradle build script kotlinlang.org/docs/reference/using-gradle.html
  • @Evgesha 我在我的回答中添加了对你问题的回答
  • 我正在尝试应用此答案,但我不确定将其放在我的 build.gradle.kts 文件中的哪个位置。如果我直接把它放在tasks 中,kotlinOptions 将无法识别。如果我把它放在tasks > compileKotlin 中,我会在["-Xjvm-default=compatibility"] 上得到“不支持[注释之外的集合文字]”作为错误。
【解决方案2】:

自 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.

【讨论】:

    【解决方案3】:

    在根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"
        }
    }
    

    【讨论】:

      【解决方案4】:

      这个关于@JvmDefault 的问题似乎与to this one 很相似。

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

      【讨论】:

        【解决方案5】:

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

        关于传递-Xjvm-default 标志:

        行家

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

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

        想法

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

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

        @JvmDefault 在 kotlin > 1.4 中不是必需的,但可能存在特殊情况,manual 应该有助于确定需要哪种注释和标志组合。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-06-08
          • 1970-01-01
          • 2015-02-01
          • 2021-07-29
          • 2023-03-03
          • 2018-06-19
          • 1970-01-01
          相关资源
          最近更新 更多