Kotlin中空判断处理操作实例

Kotlin中的一个伟大创前举就是空指针的处理,在代码的编译阶段就能检测可能出现的空指针问题,示例代码如下:

data class Person(var name: String? = null)

fun sayHello(name: String) {
    println("Hello $name")
}

fun main() {
    val person = Person("Even")
    if (person.name != null) {
        sayHello(person.name)
    }
}

在IntelliJ中,如上代码会报错,如下:

提示的错误信息翻译为:智能强制转换为’String’是不可能的,因为’person.name’是一个可变属性,此时可能已经被更改了。

要想编译通过,需要这样做:

sayHello(person.name!!)

哎?我记得学Kotlin的时候有解释说如果已经判断了不是空了的话,就不需要添加 !! 符号的,为什么这里不添加的话会报错呢?其实原因就是报错信息上提示的,因为name是用var修饰的,而且这是一个成员变量,虽然你做了非空的判断,但是判断之后,这个成员属性有可能在其它线程被修改了,比如在其他线程设置为null了,所以,这样的话就会出现空指针异常了,所以添加 !! 符号来解决报错不是最佳实践,在我这个示例中,我们知道没有开多线程去修改person的name属性,所以可以加 !! 来解决,但是最好不要这样做,如果我们知道name属性不会被修改,则可以使用val修饰,如下:

可以看到,此时不需要添加 !! 也不报错了,因为IDE知道name是一个不可变属性,判断了不是空之后,就永远不可能是空了。

有时候,name属性就需要发生变化,就必须声明为var,此时怎么解决呢?,可以通过添加局部变量解决,如下:

如上代码,IDE没有报错。我们通过添加一个val类型的name局部变量来保存person.name的值,这样的话,判断了name为不为空之后,即使person.name在子线程被设置为空了,但是局部变量name不会受到影响。我们在阅读一些系统源码的时候,不论是Java源码或是Kotlin的源码,经常发现别人在判断一个对象的属性的可空性的时候,都是先声明一个局部变量保存该对象属性再来判断,不懂事的时候就会奇怪别人为什么要多此一举,现在明白了,别人是为了预防直接判断对象属性出现的多线程修改带来的问题。

添加局部变量的话,即使是var类型的局部变量IDE也能判断是否为空,示例如下:

如上代码,可以看到,局部变量name是可变类型的,但是也不需要添加 !! 符号,因为var类型的局部变量不会被子线程修改,所以判断了不为空之后就不会为空。最后赋值了”Lily“,然后传给sayHello(name),这里并没有做非空判断啊,sayHello接受的是不可空的String,但是name是一个可空String啊,道理也很简单,因为这是局部变量,没有子线程的干扰,IDE能检测到name在传给sayHello之前是赋值了”Lily"的,之后没有再赋值为null也是能检测出来的,所以这里不需要做可空判断也能编译通过。如果没有赋值“Lily",则IDE就不知道name是否为空了,就会报错,如下:

或者,如果我们使用的是一个成员变量,即使前一句代码赋值了下一句就用也是会报错的,原因就是它有可能在子线程被设置为null了,如下:

所以,Kotlin是真的很强,如果你在使用一个变量,只要IDE没报错,你就可以放心的使用,不需要做空判断,你可以放心,运行时不会有空指针问题的。如果IDE报错了,就是有可能发生空指针的,此时你就不要强制添加 !! 来逃避问题了,一定要做合理的空指针判断处理。如果你使用Java的话,要不要做空指针处理IDE是没有提示的,你只能自己用脑子去想要不要做空指针判断处理,事实往往是我们根本就不去想要不要做处理,或者即使思考过了,也会有思考出错的时候,比如可能出现空指针的地方,但是你写代码时你认为不会出现空指针,所以你没做非空判断处理,则运行时就有可能出现空指针异常了。而Kotlin就会有提示,只要IDE没报错就不用做空指针处理,只要IDE报错了就要做空指针处理,这真是爽歪歪啊,你不需要去思考什么时候应该添加空指针判断处理了!

注:这个可空判断也适用于类型智能转换,这个知识点在官网教程上也找到了答案:https://kotlinlang.org/docs/typecasts.html#unsafe-cast-operator,相关内容如下:

Note that smart casts work only when the compiler can guarantee that the variable won’t change between the check and the usage. More specifically, smart casts can be used under the following conditions:

val local variables - always, with the exception of local delegated properties.

val properties - if the property is private or internal or if the check is performed in the same module where the property is declared. Smart casts cannot be used on open properties or properties that have custom getters.

var local variables - if the variable is not modified between the check and the usage, is not captured in a lambda that modifies it, and is not a local delegated property.

var properties - never, because the variable can be modified at any time by other code.

附:?.和!!.

其实kotlin是非常人性话的,你定义了一个可为空的变量但是你依然可以去操作的。我们修改一下上面的写法:

val a:String = "我加小明"
val b:String ?= null
val c:String? = "我加小明"

  println(a.length)
  println(b?.length)
   println(c!!.length)

这样编译就通过。

这里的**?.**就是相当于Java的如果为空就返回null 而kotlin强制让我们去处理,这样就避免了很多空指针异常

if(b==null) return null;

当然如果你不想直接为null,你说当为空时我想自己去处理,kotlin还有语法**?:**

val b:String ?= null
 println(b?.length?:"我错了")

!!. 表示我任性,告诉编译器不要去做非空检查,为空就抛异常

总结

到此这篇关于Kotlin中空判断处理操作的文章就介绍到这了,更多相关Kotlin空判断处理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Kotlin实用语法糖空安全类型转换及相等性判断

    前言 Kotlin被Google官方认为是Android开发的一级编程语言.今天,我将主要讲解,关于Kotlin的一些实用语法糖,主要包括: 范围使用:in.downTo.step.until 类型检查 & 转换:is.智能转换.as 相等性:equals().== . === 空安全 1. 范围使用 主要用于表示范围,主要包括:in.downTo.step.until /** * 1. in * 作用:在...范围内 **/ // 表示:若i在1-5范围内,则执行下面代码 // 注:闭区间,[

  • Kotlin中空判断处理操作实例

    Kotlin中的一个伟大创前举就是空指针的处理,在代码的编译阶段就能检测可能出现的空指针问题,示例代码如下: data class Person(var name: String? = null) fun sayHello(name: String) { println("Hello $name") } fun main() { val person = Person("Even") if (person.name != null) { sayHello(perso

  • JDBC中resutset接口操作实例详解

    本文主要向大家展示JDBC接口中resutset接口的用法实例,下面我们看看具体内容. 1. ResultSet细节1 功能:封锁结果集数据 操作:如何获得(取出)结果 package com.sjx.a; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import org.junit.Test; //1. next方

  • IOS中各种手势操作实例代码

    先看下效果 手势相关的介绍 IOS中手势操作一般是 UIGestureRecognizer 类的几个手势子类去实现,一般我们用到的手势就这么5种: 1.点击  UITapGestureRecognizer 2.平移  UIPanGestureRecognizer 3.缩放  UIPinchGestureRecognizer 4.旋转  UIRotationGestureRecognizer 5.轻扫  UISwipeGestureRecognizer 我们上面这个实例中就用到了上面这5种手势,不

  • Python 文件读写操作实例详解

    一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法.1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()2.返回指定目录下的所有文件和目录名:os.listdir()3.函数用来删除一个文件:os.remove()4.删除多个目录:os.removedirs(r"c:\python")5.检验给出的路径是否是一个文件:os.path.isfile()6.检验给出的路径是否是一个目录:os.path.isdir()7.判断是

  • golang针对map的判断,删除操作示例

    本文实例讲述了golang针对map的判断,删除操作.分享给大家供大家参考,具体如下: map是一种key-value的关系,一般都会使用make来初始化内存,有助于减少后续新增操作的内存分配次数.假如一开始定义了话,但没有用make来初始化,会报错的. 复制代码 代码如下: package main import ( "fmt" ) func main(){ var test =  map[string]string{"姓名":"李四",&qu

  • 数据结构 栈的操作实例详解

    数据结构 栈的操作实例详解 说明: 往前学习数据结构,想运行一个完整的顺序栈的程序都运行不了,因为书上给的都是一部分一部分的算法,并没有提供一个完整可运行的程序,听了实验课,自己折腾了一下,总算可以写一个比较完整的顺序栈操作的小程序,对于栈也慢慢开始有了感觉.下面我会把整个程序拆开来做说明,只要把这些代码放在一个文件中,用编译器就可以直接编译运行了. 一.实现 1.程序功能 关于栈操作的经典程序,首当要提及进制数转换的问题,利用栈的操作,就可以十分快速地完成数的进制转换. 2.预定义.头文件导入

  • C#实现判断当前操作用户管理角色的方法

    本文实例讲述了C#实现判断当前操作用户管理角色的方法.分享给大家供大家参考.具体实现方法如下: /// <summary> /// 判断当前操作用户的管理角色 /// </summary> public static void GetCurrentUserRole() { AppDomain appDomain = System.Threading.Thread.GetDomain(); appDomain.SetPrincipalPolicy(System.Security.Pr

  • 基于node.js的fs核心模块读写文件操作(实例讲解)

    node.js 里fs模块 常用的功能 实现文件的读写 目录的操作 - 同步和异步共存 ,有异步不用同步 - fs.readFile 都不能读取比运行内存大的文件,如果文件偏大也不会使用readFile方法 - 文件大分流读取,stream - 引入fs模块 - let fs=require('fs') 同步读取文件 -fs.readFileSync('路径',utf8); let result=fs.readFileSync('./1.txt','utf8'); 异步读取文件,用参数err捕获

  • jquery 实现复选框的全选操作实例代码

    jquery 实现复选框的全选操作实例代码 最近做了个需求,需要实现列表复选框的全选/取消全选操作,由于之前对这块不是很了解,所以从网上查了一些资料,虽然有各种实现方法,但没找到直接可以套用的.自己琢磨了下,把功能实现,整理如下. 实现细节如有可改进的地方,不吝赐教. 首先是html部分的代码,这里有一个表格,表格里面有一些选项: <div id="list"> <table> <tr><td>选项1<input type=&quo

  • Android Kotlin的使用及简单实例

    Android Kotlin的使用及简单实例 写在前面的话,作为一个不熬夜的人,一觉醒来发现Kotlin成为了Android的官方语言,可谓是大喜过望.为了趁热打铁,我决定提前三天放出原定本周日Release的文章.希望能及时让大家了解一下Kotlin. 相信很多开发人员,尤其是Android开发者都会或多或少听说过Kotlin,当然如果没有听过或者不熟悉也没有关系.因为本篇文章以及博客后期的内容会涉及到很多关于Kotlin的知识分享. 在写这篇文章前的一个多月,Flipboard中国的Andr

随机推荐