【Koltlin】深入剖析Kotlin 扩展函数和扩展属性

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

背景

在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的应用无处不在,像letalsolifelycleScopeviewModelScope等等都是扩展。

扩展这么神奇,那它到底是何物呢?从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<
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值