美文网首页
Kotlin的空安全

Kotlin的空安全

作者: 132xin | 来源:发表于2020-11-06 13:15 被阅读0次

在许多的编程语言(例如Java)中最常见的遇到的陷阱之一,就是访问引用的成员会导致空指针异常的情况(NullPointerException),在Kotlin中的做了空安全的设计,从而避免了NullPointerException。

Kotlin的空安全设计

简单来说就是通过IDE的提示来避免调用null的对象,从而避免了NullPointerException,在androidx里就有通过一个@NonNull的注解就可以标记变量是否为空,然后IDE会帮助检查。到了Kotlin这里就有了语言级别的支持,IDE的提示级别从警告变成了错误,拒绝编译。接下来看看Kotlin的实现空安全做了哪些措施。

变量默认都是不为空的
image.png

可以看到在上面的定义的时候赋值为空的时候,编译器就会提示出现错误,所有的默认变量都是不允许为空的。那么有时间在请求服务器数据的时候,有一些变量是会出现为空的情况,那该怎么办呢?
可以在变量的类型上面加上一个?号,这样就可以解除非空的限制。


image.png

那么这样不是还是会出现空指针异常的情况吗。

安全的调用(?.)

在上面提到通过?号可以解除非空的限制,既然赋值可能会出现为空,那么为了避免空指针的异常,kotlin的做法就是在调用方进行处理——安全的调用。通过?.的方式进行调用。


image.png

上面的?.的意思就是,如果str非空,就返回b.length,否则返回null。如果最后返回为null的话,我们还可以进行一步的处理。

使用Elvis操作符?:

在上面提到的如何str为空,那么length返回为空,这样好像也不太好,这是我们可以使用Elvis操作符:


image.png

意思就是当前面为空的时候就返回-1。Elvis还有另一种常见的用法:


image.png 上面的写法就等价与下面的:可以看到进一步简化了代码。
image.png

!!操作符

!!是非空断言运算符,也是避免空指针异常的手段方式之一,若该值为空则抛出异常。


image.png

意思就编译器不再帮助检查,有什么后果需要程序员去承担,这种方式,实际上和Java就没上两样了。

安全的类型转换

如果对象不是目标类型,那么常规类型转换可能会导致 ClassCastException。 另一个选择是使用安全的类型转换,如果尝试转换不成功则返回 null:

 val aInt: Int? = a as? Int

可控类型的集合

如果你有一个可空类型元素的集合,并且想要过滤非空元素,你可以使用 filterNotNull 来实现:

val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()

Kotlin的空安全设计,带来了很多好处,但是有的时候我们不一定能在定义的时候赋值,例如在Android开发的时候初始化一个控件的时候,findViewById()是需要在onCreate之后就调用的,那么这种情况怎么处理比较合适呢?

一:利用lateinit关键字进行延迟初始化

延迟初始化的意思是,告诉编译我无法第一时间去初始化,但是在使用前肯定会完成初始化。

    private lateinit var textView:TextView
    override fun onCreate(savedInstanceState: Bundle?) {
      
        textView=findViewById(R.id.textView)
    }

但是延迟初始化并不好,这样跟Java的属性没什么区别了,体验不到了空安全设计到带来的好处,而且 lateinit只能修饰var的属性,那么val的呢?

二:利用by Lazy惰性初始化

lazy()是接受一个 lambda 并返回一个 Lazy <T> 实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用 get() 只是返回记录的结果。也就是说只有第一次调用该属性的时候,委托方法才会被执行。并且只能修饰val的属性。
为了进一步安全使用,上面的TextView的初始化,就可以使用by lazy()了

    private val textView by bindView<TextView>(R.id.textView)
    
    private val Activity.viewFind:Activity.(Int)->View?
        get()={
            findViewById(it)
        }

     fun <V:View> Activity.bindView(id:Int):Lazy<V> = lazy{
        viewFind(id) as V
    }

参考链接:
https://kaixue.io/kotlin-basic-1/

相关文章

  • Android开发kotlin学习(二)

    1.kotlin的空安全 为啥子说kotlin是空安全的?和Java相比,kotlin的空安全可以带来哪些便利之处...

  • Kotlin - 空安全

    1.Kotlin空安全介绍 Kotlin空安全可消除来自代码空引用的危险。 2.什么是空引用? 许多编程语言(包括...

  • Kotlin学习之空安全

    Kotlin学习之空安全 Kotlin相对于Java有许多改良的地方,空安全就是其中的一部分,Kotlin因此解决...

  • 2017-07-18-kotlin Android基础

    kotlin Android基础 1,实现一个基本的数据类 2,空安全: Kotlin,如很多现代的语言,是空安全...

  • Kotlin null 检测机制、空安全、空指针问题

    空安全 Kotlin 引入可空类型、非空类型 Kotlin 的类型系统旨在消除来自代码空引用的危险 许多编程语言(...

  • Kotlin空安全

    可空类型与非空类型 在 Kotlin 中,类型分为可空引用和非空引用。例如,String 类型的常规变量不能容纳 ...

  • Kotlin 空安全

    简介   Kotlin 的类型系统旨在从我们的代码中消除 NullPointerException。减少线上Nul...

  • Kotlin 空安全

    可空类型与非空类型 在 Kotlin 中,类型区分引用可以为 null (可空引用),或不能为 null(非空引用...

  • Kotlin(空安全)

    空安全 可空类型和非空类型 在 Kotlin 类型系统中可以为空和不可为空的引用是不同的。比如,普通的 Strin...

  • Kotlin 空安全

    前言 当我们使用 Java 开发的时候,如果不想遇到 NullPointerException,我们就需要在使用它...

网友评论

      本文标题:Kotlin的空安全

      本文链接:https://www.haomeiwen.com/subject/paktbktx.html