背景
在kotlin中经常看到这样的if语句:
//s是一个String类型的对象
if(s.isNullOrEmpty()){
//执行空对象或空字符串的逻辑
}
笔者不禁想问,如果s是空对象,调用它的函数不会抛出空指针吗?
它是如何检查被调用的对象s是空对象的呢?
查阅资料后,发现原来这是kotlin的扩展函数的特性:
被扩展的类后面添加?.再接扩展函数名即表示可以在空对象上扩展。在扩展函数内, 可以通过 this 来判断接收者是否为 NULL,这样,即使接收者为 NULL,也可以调用扩展函数。例如:
fun Any?.toString(): String {
if (this == null) return "null"
// 空检测之后,“this”会自动转换为非空类型,所以下面的 toString()
// 解析为 Any 类的成员函数
return toString()
}
fun main(arg:Array<String>){
var t = null
println(t.toString())
}
看一下isNulOrEmpty函数的实现:
@kotlin.internal.InlineOnly
public inline fun CharSequence?.isNullOrEmpty(): Boolean {
contract {
returns(false) implies (this@isNullOrEmpty != null)
}
return this == null || this.length == 0
}
可以看到,当被调用对象是NULL时它返回true。并且返回类型Boolean是一个非空对象,所以isNullOrEmpty函数无论如何要么返回true要么返回false不可能是NULL。
扩展在kotlin的应用无处不在,像let、also、lifelycleScope、viewModelScope等等都是扩展。
扩展这么神奇,那它到底是何物呢?从kotlin官方文档来看,也看不出个究竟:
https://book.kotlincn.net/text/extensions.html
官方文档只说了它的特点,并没有深入介绍:
扩展是静态解析的
扩展不能真正的修改他们所扩展的类。通过定义一个扩展,并没有在一个类中插入新成员, 只不过是可以通过该类型的变量用点表达式去调用这个新函数。
笔者动手写了一个demo,从字节码指令窥探一下它的原理。
Kotlin扩展函数和扩展属性的原理
在com.devnn.bean目录下新建一个名为MyExtension.kt的文件,内容如下:
package com.devnn.bean
import com.devnn.demo.MainActivity
//扩展属性
val MainActivity.myExtProperty: String
get() {
val data: String? = this.getData()
return<

本文深入探讨Kotlin中的扩展函数和属性原理,解释了如何在空对象上调用这些扩展,并通过字节码分析揭示了其背后的工作机制。
最低0.47元/天 解锁文章
2613

被折叠的 条评论
为什么被折叠?



