【问题标题】:How to use Java 8 feature of default method in interface written in Kotlin如何在 Kotlin 编写的接口中使用 Java 8 的默认方法特性
【发布时间】:2020-03-02 21:14:19
【问题描述】:

我在 java 中有一个类 A,在 Kotlin 中有一个接口 B。

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

我想在 Kotlin 接口 (B) 中编写默认方法(Java 8 特性),并希望在类 A 中实现它。 我怎样才能实现它?

提前致谢。

【问题讨论】:

  • 如果你已经在类中实现了它,为什么要添加它作为默认方法?这没有任何意义。
  • Kotlin 中没有 default 关键字,您可以提供一个方法体,然后将其作为默认值。
  • default 方法应该在接口内实现..不过可以进一步覆盖。
  • @Naman 是的,但不仅仅是这样。它们并不是真的要添加到新界面中,而是要在不破坏向后兼容性的情况下为旧界面添加新功能。

标签: java kotlin java-8 interface default-method


【解决方案1】:

在 Kotlin 中,带有主体的接口方法默认编译如下:

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

大致编译为:

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

然后,在实现此接口的 Kotlin 类中,编译器会自动为 optional 方法添加覆盖,并在那里调用 B.DefaultImpls.optional(this)

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

但是,如果您想在 Java 中实现此接口并避免必须重写 optional 方法并手动调用 B.DefaultImpls 怎么办?在这种情况下,您可以使用the experimental @JvmDefault feature

首先,您需要启用几个编译器选项:

  • JVM 目标字节码版本 1.8 或更高版本:-jvm-target 1.8
  • 启用 JVM 默认方法:-Xjvm-default=enable(通过上面的链接查看其他可用的选项值)

然后,你用@JvmDefault注解来注解optional方法:

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

它被编译成

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

现在这个接口的Java实现就变成了:

public final class A implements B {
}

【讨论】:

  • 请问在哪里添加启用这个JVM默认方法:-Xjvm-default=enable
  • @sharma.mahesh 这是您应该传递给编译器的命令行选项。在 Gradle 中,这可以通过将其添加到 kotlinOptions.freeCompilerArgs 列表来完成。有关指定 kotlinOptions 的 Android 示例,请参阅此问题及其答案stackoverflow.com/questions/44141076/…
【解决方案2】:

只要有除A 之外的其他类实现B,这可能是有道理的。否则,您要么不需要默认实现,要么不必在实现类中实现该方法。

但是,您可以这样做:

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

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

【讨论】:

    猜你喜欢
    • 2021-02-03
    • 2019-04-05
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    相关资源
    最近更新 更多