Learning -Xjvm-default=all and Xjvm-default=all-compatibility in Kotlin
Tags: kotlin
Published: 2020-07-19 03:03:46

Introduced on the [official Kotlin blog](https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-m3-generating-default-methods-in-interfaces/) about generating default methods in interfaces. `-Xjvm-default=all`, `-Xjvm-default=all-compatibility` options are avaiable in Kotlin 1.4. To use advantage of these, you need to target Java 8, which allows you to generate methods in your interface by default. Let's try it.

## Try using -Xjvm-default=all
The following code is the sample code. Define `sleep()` in the `Animal` interface. The `Dog` class inherits the `Animal` interface and calls `Dog().sleep()` in `main()`.

```kotlin
// Main.kt 

fun main() {
    Dog().sleep()
}

class Dog : Animal

interface Animal {
    fun sleep() {
        println("The animal sleeps.")
    }
}
```
This time, I'm using IntelliJ IDEA, which allows you to easily reference the bytecode of Kotlin code and decompile it. For the procedure, select `Tools` -> `Kotlin` -> `Show Kotlin Bytecode`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4k267bylmq4myrmpv8wq.png)

Then, the bytecode is displayed, so if you click the `Decompile` button, it will be decompiled. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0nkie0xts71k2l45fd3i.png)

So far, I have introduced the decompilation procedure. Let's set the `-Xjvm-default=all` option. Select `IntelliJ IDEA` -> `Preferences` -> `Build, Execution, Deployment` -> `Compiler` -> `Kotlin Compiler`. Select `Language version` and `API version` to `1.4`, set `-Xjvm-default=all` to `Additional command line parameters`, and finally set `Target JVM version` to `1.8`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4kqzoimznu1ycoeqxdxk.png)

Now let's decompile. The following code is the decompiled code.

```java
// MainKt.java
import kotlin.Metadata;

@Metadata(
   mv = {1, 4, 0},
   bv = {1, 0, 3},
   k = 2,
   xi = 2,
   d1 = {"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
   d2 = {"main", "", "algo"}
)
public final class MainKt {
   public static final void main() {
      (new Dog()).sleep();
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }
}
// Dog.java
import kotlin.Metadata;

@Metadata(
   mv = {1, 4, 0},
   bv = {1, 0, 3},
   k = 1,
   xi = 2,
   d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0003"},
   d2 = {"LDog;", "LAnimal;", "()V", "algo"}
)
public final class Dog implements Animal {
}
// Animal.java
import kotlin.Metadata;

@Metadata(
   mv = {1, 4, 0},
   bv = {1, 0, 3},
   k = 1,
   xi = 2,
   d1 = {"\u0000\u0010\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u0002\n\u0000\bf\u0018\u00002\u00020\u0001J\b\u0010\u0002\u001a\u00020\u0003H\u0016ø\u0001\u0000\u0082\u0002\u0006\n\u0004\b!0\u0001¨\u0006\u0004À\u0006\u0001"},
   d2 = {"LAnimal;", "", "sleep", "", "algo"}
)
public interface Animal {
   default void sleep() {
      String var1 = "The animal sleeps.";
      boolean var2 = false;
      System.out.println(var1);
   }
}
```

As you can see, `default` is set in `sleep()` of the `Animal` interface.

## Try using -Xjvm-default=all-compatibility
Let's use `-Xjvm-default=all-compatibility`. Change `-Xjvm-default=all-compatibility` to `Additional command line parameters`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/li6dwkk7dcy7xvsyl6uh.png)

Let's decompile.

```kotlin
// MainKt.java
import kotlin.Metadata;

@Metadata(
   mv = {1, 4, 0},
   bv = {1, 0, 3},
   k = 2,
   xi = 2,
   d1 = {"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
   d2 = {"main", "", "algo"}
)
public final class MainKt {
   public static final void main() {
      (new Dog()).sleep();
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }
}
// Dog.java
import kotlin.Metadata;

@Metadata(
   mv = {1, 4, 0},
   bv = {1, 0, 3},
   k = 1,
   xi = 2,
   d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0003"},
   d2 = {"LDog;", "LAnimal;", "()V", "algo"}
)
public final class Dog implements Animal {
}
// Animal.java
import kotlin.Metadata;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 4, 0},
   bv = {1, 0, 3},
   k = 1,
   xi = 2,
   d1 = {"\u0000\u0010\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u0002\n\u0000\bf\u0018\u00002\u00020\u0001J\b\u0010\u0002\u001a\u00020\u0003H\u0016¨\u0006\u0004À\u0006\u0001"},
   d2 = {"LAnimal;", "", "sleep", "", "algo"}
)
public interface Animal {
   default void sleep() {
      String var1 = "The animal sleeps.";
      boolean var2 = false;
      System.out.println(var1);
   }

   @Metadata(
      mv = {1, 4, 0},
      bv = {1, 0, 3},
      k = 3,
      xi = 2
   )
   public static final class DefaultImpls {
      public static void sleep(@NotNull Animal $this) {
         $this.sleep();
      }
   }
}
```

`default` is set for `sleep()` of the `Animal` interface. You can also see that the `DefaultImpls` are generated. This time, I introduced how to use each option. For more details, please refer to [Kotlin official blog](https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-m3-generating-default-methods-in-interfaces/).