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