资讯专栏INFORMATION COLUMN

Kotlin如何避免“!!”(非空断言)

zhongmeizhi / 1288人阅读

摘要:当我们把自动转成的时候,代码里会出现很多非空断言。如何避免使用这种是最常用的方法,也是首选的方法。由于是变量,为了避免多线程对变量的修改而出现的情况,从编译上进行了限制。代理属性如果需要对基本类型等做非空处理,可以使用代理属性。

当我们把Java自动转成Kotlin的时候,代码里会出现很多非空断言!!。或者某些场景下因为IDE提示或编译错误,也让我们自己加上了一些!!
但使用!!的后果是有可能抛出IllegalArgumentException:Parameter specified as non-null is null

如何避免!! 使用?.let/?.apply/?.run

这种是最常用的方法,也是首选的方法。但当有多个变量同时要判空时,或者需要处理为null时的逻辑,这种方式稍微有一点麻烦,下面会讲到一些新的方式。

disposable?.let {
    if (!it.isDisposed) it.dispose()
}
用Val替代Var
var mutableString:String? = null

fun run() {
    mutableString = "a"
    printText(mutableString)
}

fun printText(text: String) {
    ...
}

此时会报错`Smart cast to "String" is impossible, because "multableString" is a mutable property that could have been changed by this time
:app:compileDebugKotlin FAILED`。由于multableString是Var变量,为了避免多线程对变量的修改而出现Null的情况,kotlin从编译上进行了限制。

解决方法1是把var变量改为val变量

val mutableString:String = "a"

fun run() {
    printText(mutableString)
}

解决方法2是写一个新的val变量,将var变量赋值给它,将val作为参数

fun run() {
    mutableString = "a"
    val string = mutableString ?: ""
    printText(string)
}
使用Elvis操作符
fun run() {
    multableString = "a"
    printText(multableString ?: "")
}
声明lateinit

使用lateinit声明到变量上,表示这个变量延迟初始化,比较适合在Activity.onCreate这种有生命周期的方法里初始化。

lateinit var mutableString: String
override fun onCreate(savedInstanceState: Bundle?) {
    multableString = "a"
    printText(mutableString)
}
需要注意的是,访问未初始化的 lateinit 修饰的属性会抛出UninitializedPropertyAccessException异常

注意:基本类型是不能使用lateinit的。会抛错"lateinit" modifier is not allowed on properties of primitive types

lateinit var mutableInt: Int
代理属性

如果需要对基本类型等做非空处理,可以使用代理属性。

var mutableInt: Int by Delegates.notNull()
override fun onCreate(savedInstanceState: Bundle?) {
    mutableInt = 1
}

一定要在初始化赋值之后才能读取mutableInt,不然会抛IllegalStateException:Property ${property.name} should be initialized before get.

空与非空处理
val result = multableString.notNullElse {
    "$it is not null"
} ({ "is null" })

新开发的方法notNullElse,对单个变量判空处理,非空时传入it为非空类型,提高了便捷性,为空时使用第二个block来返回值。适合那里需要判空,返回值result也是非空的类型,比较实用。源码在此下载

多个值非空
private var mLinearLayout: LinearLayout? = null

...
private fun initView(context: Context) {
    mLinearLayout = LinearLayout(context)
}

...

if (tvItem == null) {
    mLinearLayout!!.addView(childTvItem)
} else {
    mLinearLayout!!.addView(childTvItem, mLinearLayout!!.indexOfChild(tvItem) + 1)
}

当我们要对多个值判断的时候,let就不那么好用了,但如果不使用let就拿不到非空的类型,像上面要判断2个都不为空时做操作,为空时另外一个逻辑。其实一早我们就已经判断空了,有没有更好的方法呢?

allNotNullElse(tvItem, mLinearLayout) { a, b ->
    b.addView(childTvItem, b.indexOfChild(tvItem) + 1)
} ({ mLinearLayout?.addView(childTvItem) })

新开发的方法allNotNullElse返回的a, b 两个值已经是非空类型了,这样addView使用的也是非空类型,使用起来更方便了。源码在此下载

喜欢这篇文章,请点赞收藏,谢谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/14511.html

相关文章

  • Kotlin可空性探索

    摘要:可空性在中,类型系统区分一个引用是可以容纳可空引用还是不能容纳非空引用。使用可以很方便得将可空转为非空,但可空变量值为,则会。 目录介绍 01.可空性 02.安全调用运算符:?. 03.Elvis运算符:?: 04.安全转换运算符:as? 05.非空断言:!! 06.let函数说明 07.可空类型的扩展 08.Java中判断方式 09.kotlin是否解决NPE 10.kotlin如...

    DataPipeline 评论0 收藏0
  • 从零开始学 Kotlin 之「2」数据类型

    摘要:前言大家好,这里是从零开始学之数据类型,本文首发于公众号,欢迎前往大家关注。输出布尔类型中的布尔类型用表示,它的值有和。若需要可空引用时,布尔类型的值会被装箱。此时程序会抛出异常最后从零开始学之数据类型到这里就结束了。 前言 大家好,这里是「从零开始学 Kotlin 之『2 』数据类型」,本文首发于公众号「Binguner」,欢迎前往大家关注。我会每周分享一些关于 Android 和...

    LuDongWei 评论0 收藏0
  • 从零开始学 Kotlin 之「2」数据类型

    摘要:前言大家好,这里是从零开始学之数据类型,本文首发于公众号,欢迎前往大家关注。输出布尔类型中的布尔类型用表示,它的值有和。若需要可空引用时,布尔类型的值会被装箱。此时程序会抛出异常最后从零开始学之数据类型到这里就结束了。 前言 大家好,这里是「从零开始学 Kotlin 之『2 』数据类型」,本文首发于公众号「Binguner」,欢迎前往大家关注。我会每周分享一些关于 Android 和...

    Awbeci 评论0 收藏0
  • Kotlin 极简教程 》第4章 基本数据类型与类型系统

    摘要:本章我们来学习一下的基本数据类型与类型系统。字符串就是一个抽象数据类型。如果程序语言的语法中含有类型标记,就称该语言是显式类型化的,否则就称为隐式类型化的。但是,可以把中对应的这几种基本数据类型,理解为的基本类型的装箱类。 第4章 基本数据类型与类型系统 《Kotlin极简教程》正式上架: 点击这里 > 去京东商城购买阅读 点击这里 > 去天猫商城购买阅读 非常感谢您亲爱的读...

    MoAir 评论0 收藏0
  • Kotlin入门(28)Application单例化

    摘要:而开展该工作的基础,是必须获得对象的唯一实例,也就是将单例化。一手工声明属性的单例化该方式与的常见做法一致,也是手工声明自身类的静态实例,然后通过静态方法返回自身实例。Application是Android的又一大组件,在App运行过程中,有且仅有一个Application对象贯穿应用的整个生命周期,所以适合在Application中保存应用运行时的全局变量。而开展该工作的基础,是必须获得A...

    dance 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<