Kotlin interface default method
前言
java 在 1.8 之前,interface 是沒(méi)有默認(rèn)方法的。但是 kotlin 是支持在接口中定義一個(gè)默認(rèn)方法的。那么 kotlin 是怎么實(shí)現(xiàn)的呢?本文將帶你一探究竟。
Show me the code
interface TestInterface {
fun method1() {
println("default impl for method1() called")
}
fun method2()
}
class TestInterfaceCaller {
fun getTestInterfaceImpl(): TestInterface {
return object : TestInterface {
override fun method2() {
println("method2 called")
}
}
}
}
如代碼所示,我們定義了一個(gè)簡(jiǎn)單的 interface 叫 TestInterface,然后在里面有兩個(gè)方法:method1 和 method2 。其中,method1 是默認(rèn)方法,提供了一個(gè)默認(rèn)實(shí)現(xiàn)。然后,在使用方,也就是 TestInterfaceCaller 中,返回了一個(gè) object : TestInterface對(duì)象。這個(gè)對(duì)象就相當(dāng)于 java 中的匿名內(nèi)部類(lèi)。然后,我們發(fā)現(xiàn),ide 要求我們必須要實(shí)現(xiàn) method2 方法,而 method1 方法不用實(shí)現(xiàn)。這符合我們的直觀(guān)認(rèn)知:因?yàn)?method1 方法是當(dāng)做一個(gè)接口的默認(rèn)方法來(lái)用的,method2 方法是一個(gè)接口的普通方法,所有實(shí)現(xiàn)這個(gè)接口的對(duì)象都要實(shí)現(xiàn)這個(gè) method2 方法。
kotlin 怎么實(shí)現(xiàn)的?源碼面前,了無(wú)秘密。
kotlin 是怎么實(shí)現(xiàn) interface 默認(rèn)方法的呢?要知道 java1.8 才實(shí)現(xiàn)的功能,kotlin 其實(shí)不要求版本就能實(shí)現(xiàn)。jvm 又不可能針對(duì) kotlin 來(lái)單獨(dú)開(kāi)一個(gè)后門(mén)。要想知道 kotlin 是怎么實(shí)現(xiàn)的,我們需要對(duì)相關(guān)代碼做一個(gè)反編譯。結(jié)果如下:
public interface TestInterface {
void method1();
void method2();
public static final class DefaultImpls {
public static void method1(TestInterface $this) {
String var1 = "default impl for method1() called";
boolean var2 = false;
System.out.println(var1);
}
}
}
public final class TestInterfaceCaller {
@NotNull
public final TestInterface getTestInterfaceImpl() {
return (TestInterface)(new TestInterface() {
public void method2() {
String var1 = "method2 called";
boolean var2 = false;
System.out.println(var1);
}
public void method1() {
TestInterface.DefaultImpls.method1(this);
}
});
}
}
源碼面前,了無(wú)秘密。我們可以看到,對(duì)于 interface 中的默認(rèn)方法 method1,kotlin 其實(shí)有一個(gè) trick:在編譯期間會(huì)生成一個(gè) DefaultImpls 的靜態(tài)類(lèi),在里面有 method1 的實(shí)現(xiàn)。而在使用方,會(huì)在編譯期間進(jìn)行替換,把未實(shí)現(xiàn)的方法實(shí)現(xiàn)為對(duì) DefaultImpls 中的靜態(tài)方法的調(diào)用。