简体   繁体   English

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

[英]When a kotlin lambda is effectively converted into java SAM?

considering this bit of code 考虑这段代码

java side : java方面:

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

kotlin side: 科特林方面:

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

Is SAM transformation done at the variable declaration line var runner: () -> Unit = {} or at the execute() function ? SAM变换是在变量声明行var runner: () -> Unit = {}还是在execute()函数中完成的?

Is runner reference inside execute scope is different from runner declaration ? 内部执行范围内的runner参考是否与runner声明不同?

The conversion takes place at call site, ie when the Runnable is actually needed. 转换发生在呼叫站点,即实际需要Runnable时。 Have a look at what is being generated by the compiler (represented in Java code): 看一下编译器生成的内容(用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(...)");
   }
}

The above code shows that an implementation of Runnable is generated by the compiler, which takes a Function as its construction parameter. 上面的代码显示了编译器生成Runnable的实现,它将Function作为其构造参数。 in the run implementation that function is simply being invoked. 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);

The call side shows how the lambda, compiled to a Function object gets converted into the proper Runnable instance. 调用方显示如何将编译为Function对象的lambda转换为正确的Runnable实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM