考虑这段代码
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
声明不同?
答案 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
实例。