Как использовать функцию Java 8 метода по умолчанию в интерфейсе, написанном на Kotlin
У меня есть класс A в java и интерфейс B в Kotlin.
// kotlin
interface B {
fun optional()
}
// java
class A implements B {
}
Я хочу написать метод по умолчанию (функция Java 8) в интерфейсе Kotlin (B) и хочу реализовать его в классе A. Как я могу этого добиться?
Заранее спасибо.
2 ответа
В 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
вручную? В этом случае вы можете использовать экспериментальный@JvmDefault
особенность.
Во-первых, вам нужно включить пару параметров компилятора:
- Целевой байт-код JVM версии 1.8 или выше:
-jvm-target 1.8
- включить методы JVM по умолчанию:
-Xjvm-default=enable
(см. другие доступные значения параметров по ссылке выше)
Затем вы комментируете optional
метод с @JvmDefault
аннотация:
// 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 {
}
Пока есть другие классы, кроме A
реализация B
, это может иметь смысл. В противном случае вам либо не нужна реализация по умолчанию, либо вам не нужно реализовывать этот метод в классе реализации.
Однако сделать это можно так:
interface B {
fun optional() { print("optional") }
}
class A implements B {
override fun optional() { print("B's optional") }
}