什么时候kotlin lambda有效地转换成java SAM?

时间:2018-02-15 10:30:23

标签: lambda kotlin

考虑这段代码

java方面:

public class Executor {
    public void execute (Runnable runner) { /* do something with runner */ }
}
kotlin方面:

val executor = Executor() 
var runner: () -> Unit = { } // expected Runnable
executor.execute(runner)

SAM转换是在变量声明行var runner: () -> Unit = {}还是execute()函数处完成的?

执行范围内的runner引用是否与runner声明不同?

1 个答案:

答案 0 :(得分:3)

转换发生在呼叫站点,即实际需要Runnable时。看看编译器生成的内容(用Java代码表示):

final class FileKt$sam$Runnable$9c7e667b implements Runnable {

   private final Function0 function;

   FileKt$sam$Runnable$9c7e667b(Function0 var1) {
      this.function = var1;
   }

   public final void run() {
      Intrinsics.checkExpressionValueIsNotNull(this.function.invoke(), "invoke(...)");
   }
}

上面的代码显示编译器生成Runnable的实现,它以Function作为构造参数。在run实现中,该函数只是被调用。

//the call

Executor executor = new Executor();
Function0 runner = (Function0)null.INSTANCE;
Object var10001 = runner;
if (runner != null) {
   var10001 = new FileKt$sam$Runnable$9c7e667b(runner);
}

executor.execute((Runnable)var10001);

调用方显示编译为Function对象的lambda如何转换为正确的Runnable实例。