kotlin

Kotlin interface default method

2020-04-04  本文已影响0人  弄码哥nomag

Kotlin interface default method

前言

java 在 1.8 之前,interface 是没有默认方法的。但是 kotlin 是支持在接口中定义一个默认方法的。那么 kotlin 是怎么实现的呢?本文将带你一探究竟。

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")
            }
        }
    }
}

如代码所示,我们定义了一个简单的 interface 叫 TestInterface,然后在里面有两个方法:method1 和 method2 。其中,method1 是默认方法,提供了一个默认实现。然后,在使用方,也就是 TestInterfaceCaller 中,返回了一个 object : TestInterface对象。这个对象就相当于 java 中的匿名内部类。然后,我们发现,ide 要求我们必须要实现 method2 方法,而 method1 方法不用实现。这符合我们的直观认知:因为 method1 方法是当做一个接口的默认方法来用的,method2 方法是一个接口的普通方法,所有实现这个接口的对象都要实现这个 method2 方法。

kotlin 怎么实现的?源码面前,了无秘密。

kotlin 是怎么实现 interface 默认方法的呢?要知道 java1.8 才实现的功能,kotlin 其实不要求版本就能实现。jvm 又不可能针对 kotlin 来单独开一个后门。要想知道 kotlin 是怎么实现的,我们需要对相关代码做一个反编译。结果如下:

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);
         }
      });
   }
}

源码面前,了无秘密。我们可以看到,对于 interface 中的默认方法 method1,kotlin 其实有一个 trick:在编译期间会生成一个 DefaultImpls 的静态类,在里面有 method1 的实现。而在使用方,会在编译期间进行替换,把未实现的方法实现为对 DefaultImpls 中的静态方法的调用。

上一篇下一篇

猜你喜欢

热点阅读