Kotlin 初探:空指针检查

本文借鉴自第一行代码 (第三版)
Test类:

    class Test{
        fun a(){
            println("调用a方法")
        }
    }

写一个用该类对象作参数的方法

    fun doSomething(a: Test){
        println(a.a())
    }

此时就会出现一个问题: 当参数为null时候会报红. 如下
在这里插入图片描述
这是因为kotlin默认所有的参数和变量都不可为空
那么问题又来了, 有时候参数需要为空怎么办? 对doSomething方法作如下修改

    fun doSomething(a: Test?){
        println(a.a())
    }

可以看到在参数类名后多了一个?, 这时该参数就表示为: 我希望传入的参数可以为空

那么问题又来了, 因为doSomething里的a方法爆红了, 如下
在这里插入图片描述
原因在于当参数为可空类型时, 调用该参数的方法都可能造成空指针异常, 在这种条件下Kotlin不允许编译通过
那么我们只需在调用前判断a是否为空就行. 对doSomething作如下修改

    fun doSomething(a: Test?){
        if (a != null) {
            println(a.a())
        }
    }

那么问题又来了, 每个方法都要这样判断是否麻烦
对此, Kotlin提供了判空辅助工具

辅助判空工具

  • ?.
    一个问号一个点, 该操作符就相当于doSomething的if判空
    对doSomething作如下修改
    fun doSomething(a: Test?){         
        println(a?.a())
    }

ok 没有报红

  • ?:
    该操作符左右两边接收一个表达式, 若左表达式的结果不为空就返回左边的结果, 反之返回右边的结果
    举个例子
    fun ke(a: String?): Int = a?.length ?: 0
  • !!
    在这里插入图片描述
    可以看到在一个类里定义实例变量text, 在main函数内先判空, 若不为空调用bs方法, 但是报红了. 这是因为bs方法不知道外部已经进行判空检查, 故认为这里存在空指针风险. 若想通过编译就可以使用!!操作符了. 该操作符表示为: 我确信这里的对象不为空, 你就不用做空指针检查了, 出现问题了后果我自己承担
  • let函数
    把Test类新增一个b方法, 在doSomething中修改如下
    fun doSomething(a: Test?){
        println(a?.a())
        println(a?.b())
    }

将该方法转换成Java代码
在这里插入图片描述
可以看到该方法内进行了两次对a的判空, 此时就可以使用let函数进行优化了
let函数的语法如下

        obj.let{ a ->
            //具体逻辑
        }

其中obj为对象, a为lambda参数, 实际上obj和a为同一对象, 此时doSomething方法就可以作如下修改

    fun doSomething(a: Test?){
        a?.let { x ->
            println(x.a())
            println(x.b())
        }
    }

由于lambda参数列表只有一个参数 (x), 可以不用声明参数名, 直接用it代替

    fun doSomething(a: Test?){
        a?.let {
            println(it.a())
            println(it.b())
        }
    }

基本上这就是Kotlin的空指针检查了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值