简体   繁体   中英

How to use Java 8 feature of default method in interface written in Kotlin

I have a class A in java and interface B in Kotlin.

// kotlin
interface B {
    fun optional()
}
// java
class A implements B {
}

I want to write the default method (Java 8 feature) in Kotlin interface (B) and want to implement it in the class A. How can I achieve it?

Thanks in advance.

In Kotlin, interface methods with bodies are by default compiled as following:

// kotlin
interface B {
    fun optional() { println("B optional body") }
}

is compiled roughly to:

public interface B {
   void optional();
   public static final class DefaultImpls {
      public static void optional(B $this) {
         System.out.println("B optional body");
      }
   }
}

Then, in Kotlin classes implementing this interface, the compiler adds an override for optional method automatically and calls B.DefaultImpls.optional(this) there.

public final class KA implements B {
   public void optional() {
      B.DefaultImpls.optional(this);
   }
}

But what if you want to implement this interface in Java and avoid having to override optional method and calling B.DefaultImpls manually? In that case you can use the experimental @JvmDefault feature .

First, you need to enable a couple of compiler options:

  • JVM target bytecode version 1.8 or higher: -jvm-target 1.8
  • enable JVM default methods: -Xjvm-default=enable (see the other available option values by the link above)

Then, you annotate optional method with @JvmDefault annotation:

// kotlin
interface B {
    @JvmDefault
    fun optional() { println("B optional body") }
}

and it becomes compiled to

public interface B {
   @JvmDefault
   default void optional() {
      System.out.println("B optional body");
   }
}

And now the Java implementation of this interface becomes just:

public final class A implements B {
}

As long as there are other classes than A implementing B , this may make sense. Otherwise you either don't need a default implementation or you don't have to implement that method in the implementing class.

However, you can do it like this:

interface B {
    fun optional() { print("optional") }
}

class A implements B {
    override fun optional() { print("B's optional") }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM