我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Kotlin中空判断处理操作实例

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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空判断处理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Kotlin中空判断处理操作实例

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何实现BAT批处理判断目录在%Path%中

本篇内容介绍了“如何实现BAT批处理判断目录在%Path%中”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!貌似没有很优美的做法,只能把%Pa
2023-06-08

Python Pandas数据处理高频操作实例分析

这篇文章主要介绍“Python Pandas数据处理高频操作实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python Pandas数据处理高频操作实例分析”文章能帮助大家解决问题。引入依赖
2023-07-02

Hibernate中怎么实现处理级联操作

本篇文章为大家展示了Hibernate中怎么实现处理级联操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Hibernate处理级联操作Java 持久性映射过程中最重要和最复杂的一环就是确定如何映射
2023-06-17

VB.NET中怎么实现事务处理操作

VB.NET中怎么实现事务处理操作,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。要定义一个事务,需要使用Begin tran命令,在这一命令之后的任何语句都将被认为是事务的
2023-06-17

C#中怎么实现文件处理操作

C#中怎么实现文件处理操作,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、什么是流?流是用来载体与载体之间传送数据的。载体是数据的载体,如:如果数据存放在硬盘
2023-06-17

Shell中处理包含空格的文件名实例

今天在处理文件时遇到个问题,当文件名包含空格时,for循环就出问题了。 例如,我在当前文件夹下建立3个文件名包含空格的文件: keakons-MacBook-Pro:test keakon$ touch "test 1"keakons-Ma
2022-06-04

C#项目中怎么实现预处理操作

C#项目中怎么实现预处理操作,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。C#预处理控制行特性#error和#warning使得代码可以把警告和错误的条件报告给
2023-06-18

VB.NET中怎么实现数据行处理操作

这期内容当中小编将会给大家带来有关VB.NET中怎么实现数据行处理操作,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Windows窗体中的数据绑定列表框和组合框很节省时间。典型的VB.NET数据行处理代码
2023-06-17

python中文件操作和异常处理的示例分析

这篇文章主要介绍python中文件操作和异常处理的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、 文件的操作1.1创建文件格式:f = open(‘文件, ‘w)或者f = open(‘文件, ‘r)1.
2023-06-22

Nodejs基于LRU算法实现的缓存处理操作示例

本文实例讲述了Nodejs基于LRU算法实现的缓存处理操作。分享给大家供大家参考,具体如下: LRU是Least Recently Used的缩写,即最近最少使用页面置换算法,是为虚拟页式存储管理服务的,是根据页面调入内存后的使用情况进行决
2022-06-04

OpenCV+Qt实现图像处理操作工具的示例代码

这篇文章主要介绍了利用OpenCV+Qt实现图像处理操作工具,可以实现雪花屏、高斯模糊、中值滤波、毛玻璃等操作,感兴趣的可以了解一下
2022-11-13

Service层讲解DAO层中异常处理操作的示例分析

这篇文章将为大家详细讲解有关Service层讲解DAO层中异常处理操作的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。domain:只是定义一个javabean。dao:对于数据库的操作,都放到d
2023-06-15

Go如何实现HTTP中间人代理的操作示例

小编给大家分享一下Go如何实现HTTP中间人代理的操作示例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!go是什么golang是一种编译语言,可以将代码编译为机器
2023-06-14

BAT批处理中文件与文件夹操作的示例分析

这篇文章将为大家详细讲解有关BAT批处理中文件与文件夹操作的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。批处理中的文件、文件夹操作,xcopy命令的用法。一,建bat文件自动执行复制,删除命令。
2023-06-08

怎么在R语言中实现数据预处理操作

本篇文章给大家分享的是有关怎么在R语言中实现数据预处理操作,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、项目环境开发工具:RStudioR:3.5.2相关包:infothe
2023-06-08

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录