在Kotlin中实现SAM接口时,Lambda表达式内this的指向为何是外部类而非SAM接口实例?
为什么SAM转换的lambda里
this指向外部类而非接口实例? 这是个非常典型的Kotlin SAM转换行为问题,咱们把它拆解清楚:
1. 先明确SAM转换的本质
你定义的WebResponseHandler是一个函数式接口(用fun interface标记),Kotlin的SAM转换允许你用lambda表达式来简化接口实现,而不用写完整的匿名内部类。
你的代码:
private val onInitWebResponseHandler: VolleyHandler.WebResponseHandler = VolleyHandler.WebResponseHandler() { Thread(ParseJsonStringOnInit(WeakReference(this), weakRefIOnAllScoresDataFirstFetched, it)).start() }
其实是VolleyHandler.WebResponseHandler(lambda)的语法糖——Kotlin允许把lambda放在括号外面,让代码更简洁。但这个lambda本身并不是WebResponseHandler的实例,它只是被用来实现接口的onWebResponseFinished方法。
2. Lambda中this的作用域规则
在Kotlin的lambda表达式里,默认情况下this指向的是包含这个lambda的外部类实例,也就是你这里的ClassA。这是因为lambda的作用域是继承自它所在的外部上下文,而不是它所实现的接口。
如果换成传统的匿名内部类写法,你就能看到区别:
private val onInitWebResponseHandler = object : VolleyHandler.WebResponseHandler { override fun onWebResponseFinished(jsonString: String?) { // 这里的this指向WebResponseHandler的实例 println(this is VolleyHandler.WebResponseHandler) // 输出true // 如果要访问外部类ClassA的实例,需要用带标签的this Thread(ParseJsonStringOnInit(WeakReference(this@ClassA), ...)).start() } }
3. 这确实是SAM转换的约定
没错,这就是Kotlin SAM转换的既定行为:lambda的上下文属于外部类,所以this默认指向外部类。如果你的逻辑需要访问WebResponseHandler的实例本身,那么SAM转换的lambda写法就满足不了,必须改用匿名内部类的方式。
内容的提问来源于stack exchange,提问作者Eitanos30
相关产品推荐
相关产品推荐

