Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@JvmDefault and how add compiler option

Tags:

I need to make a default void method in a Kotlin interface. I ran into a problem and a hint said Usage of @JvmDefault is only allowed with -Xjvm-default option.

Where do I need to write this Xjvm-default?

like image 833
Evgesha Avatar asked Dec 28 '18 20:12

Evgesha


2 Answers

@Target([AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY]) annotation class JvmDefault

Specifies that a JVM default method should be generated for non-abstract Kotlin interface member.

Usages of this annotation require an explicit compilation argument to be specified: either -Xjvm-default=enable or -Xjvm-default=compatibility.

with -Xjvm-default=enable, only default method in interface is generated for each @JvmDefault method. In this mode, annotating an existing method with @JvmDefault can break binary compatibility, because it will effectively remove the method from the DefaultImpls class.

with -Xjvm-default=compatibility, in addition to the default interface method, a compatibility accessor is generated in the DefaultImpls class, that calls the default interface method via a synthetic accessor. In this mode, annotating an existing method with @JvmDefault is binary compatible, but results in more methods in bytecode.

Removing this annotation from an interface member is a binary incompatible change in both modes.

Generation of default methods is only possible with JVM target bytecode version 1.8 (-jvm-target 1.8) or higher.

@JvmDefault methods are excluded from interface delegation.

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

if you use gradle then add this parameter to gradle script

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

for example add this to gradle:

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

otherwise if you use Kotlinc command line compiler add -Xjvm-default=compatibility after your command in command line

like image 145
ygngy Avatar answered Oct 02 '22 18:10

ygngy


The new answer since Kotlin 1.4 would be:

tasks.withType(KotlinCompile::class).all {     kotlinOptions {         jvmTarget = "11"          // For creation of default methods in interfaces         freeCompilerArgs = listOf("-Xjvm-default=all")     } } 

You can then even leave off the @JvmDefault completely!

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

like image 33
Michael Piefel Avatar answered Oct 02 '22 20:10

Michael Piefel