@JvmDefault и как добавить опцию компилятора

Мне нужно сделать default void метод в интерфейсе Kotlin. Я столкнулся с проблемой, и намек сказал, Использование @JvmDefault разрешено только с -Xjvm-default вариант.

Где мне нужно написать это Xjvm-default?

2 ответа

@Target([AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY]) класс аннотаций JvmDefault

Указывает, что метод JVM по умолчанию должен быть сгенерирован для неабстрактного члена интерфейса Kotlin.

Использование этой аннотации требует указания явного аргумента компиляции: либо -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 после вашей команды в командной строке

Новый ответ, так как Котлин 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.

В корне 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"
    }
}

Дополнительным релевантным выходом отказа может быть: is not abstract and does not override abstract method.

О прохождении -Xjvm-default флаг:

maven

в плагине configurationузел для kotlin-maven-plugin добавить

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

ИДЕЯ

в настройках (через dev.to): Build, Execution, Deployment -> Compiler -> Kotlin Compiler -> Дополнительные параметры командной строки добавить -Xjvm-default=all

в проекте Структура: Модули -> Котлин -> Дополнительные параметры командной строки добавить -Xjvm-default=all

@JvmDefault should not be necessary with kotlin > 1.4 but there may be special constellations in which the manual should help determine which combination of annotation and flag is required.

Этот вопрос относительно @JvmDefaultкажется довольно похожим на этот.

-Xjvm-default=enable Флаг должен быть передан компилятору. Так как я предполагаю, что вы не работаете с kotlinc (компилятор Kotlin) непосредственно в командной строке: эти вопросы и ответы содержат информацию о том, как передавать флаги компилятору Kotlin при использовании Gradle.

Другие вопросы по тегам