再见NullPointerException。在Kotlin里null的处理(KAD 19)
时间:Apr 4, 2017
原文链接:https://antonioleiva.com/nullity-kotlin/
关于Kotlin最重要的部分之一:无效处理,我花了很长时间完成写一篇文章。
东尼·霍尔(Tony Hoare)“空(null)”概念的创作者,自称“十亿美元的错误”。在你编写Java代码是,null是最容易出错的指针。
如果你在观察Bug管理器,我确信你见到的NullPointerException错误要超过90%。
多亏Kotlin,你将工作在更加安全的环境中(即使是用Java库),它是这些问题尽量减少。
Kotlin的Null
除非你设定,Kotlin不存在Null。
也就是说,没有变量缺省值能够被设置成null。记住,在Kotlin中所有类型都是对象。
因此,不能编译:
val x: Int = null
如果要变量接受Null,你必须为类型加上问号(?):
val x: Int? = null
编译时检查
然而,从这点来说,编译器强制你在对该变量做任何事情之前检查变量是否为null。这确保NullPointerException不会发生。
例如:
val y = x.toDouble()
如果你不先检查是否为null,则不能编译,必须这样:
if (x != null) {
val y = x.toDouble()
}
安全访问表达
有一个更容易的方法表示前面的例子,在调用方法时,在“.”之前加个问号(?)。
如果变量不是null,它将执行操作。否则,它不做任何事情:
val y = x?.toDouble()
在这种情况下,如果 x 是 null,那么表达式将返回null。所以,y将是Double?类型。
Elvis操作符
但是,如果我们不希望有一个可以为空变量作为操作结果怎么办?在这种情况下,Elvis操作符允许我们返回一个值:
val y = x?.toDouble() ?: 0.0
这行代码等效:
val y = if (x != null) {
x.toDouble()
} else {
0.0
}
注意:
如你所见,Kotlin中大多数语句都转化为表达式。例如,你能够将if的结果赋值给变量。
避免null检查
如果你确信变量不可能为null,可以用操作符(!!)可以避免null检查。
以我看,极少有情况需要这个操作符。总是有更好的解决方案。
但是,你能够这样做:
val x: Int? = null
val y = x!!.toDouble()
这能够编译,并且产生NullPointerException。
这就是为什么我说:要非常小心使用这个操作符。
Java支持
当我们使用Java库时,我们可能会发现自己要面对不同的null检查情况。
库恰当的注解
如果在Java和Android中,适当地使用@Nullable和@NotNull注解,Kotlin能够与其很好的对接,并且,能够指出变量什么时候是null,什么时候不是。
Android框架的许多部分已经正确的注解了,所以这是与Kotlin配合使用的巨大优势。
库没有注解
然而,如果库没有注解,类型将以特殊操作符(单一!)标注,这就意味着这是在我们这边决定一个参数或返回值是否接受null。
如果我们阅读源代码,最好检查代码以决定是否允许使用null。
Android没有注解的例子是RecyclerView支持库。当你创建一个适配器和生成方法时,缺省是为类型加询问。
但是,如果您查看源代码,会发现在需要覆盖的方法中,没有任何东西能够是null。
结论
对所有Java开发者,NullPointerException是个噩梦,大多数情况,这表示你的代码发生错误了。
这在Kotlin中,很容易地将这类错误几乎减少到零,即使使用Java框架和库。
只有这样,就可避免不必要的长时间的调试工作,而且可以让代码更加稳定。
如果你要进一步的学习所有这些,且能够流利创建你自己的Android APP,我建议你找这本免费书学习怎样创建你的第一个项目,或直接获取这本书,学习怎样从头开始创建一个完整的APP。
---恢复内容结束---
再见NullPointerException。在Kotlin里null的处理(KAD 19)的更多相关文章
- 优雅的运用 Kotlin 的 null safety 特性,而不要简单的直接用 !!双感叹号
对于 Null 的检查是 Kotlin 的特点之一.强制你在编码过程中考虑变量是否可为 null,因此可以避免很多在 Java 中隐藏的 NullPointerException. 但是,当你用插件直 ...
- java里null强转为某个类会报错吗?
1.定义一个User类如下: /** * @author lizhibiao * @date 2018/11/27 17:21 */public class User{ private String ...
- kotlin之null值安全性
var a: String =null // 编译错误 var a: String? =null // 编译通过 要允许null值, 需要将变量声明为可为null的字符串类型:String? fun ...
- MySQL里null与空值的辨析
CREATE TABLE `test` ( `col1` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `co ...
- 用Kotlin实现Android定制视图(KAD 06)
作者:Antonio Leiva 时间:Dec 27, 2016 原文链接:https://antonioleiva.com/custom-views-android-kotlin/ 在我们阅读有关c ...
- 在Kotlin编写RecyclerView适配器(KAD 16)
作者:Antonio Leiva 时间:Mar 14, 2017 原文链接:https://antonioleiva.com/recyclerview-adapter-kotlin/ 通过创建Recy ...
- 尝试Java,从入门到Kotlin(下)
上篇已提(tu)到(cao)Java中的各种坑.习惯了C#的各种特性和语法糖后,再转到Java感觉比较别扭.最后本着反正Java也不是很熟悉,干脆再折腾折腾其他语言的破罐子破摔的心态,逛了一圈JVM语 ...
- SQL - where条件里的!=会过滤值为null的数据
!=会过滤值为null的数据 在测试数据时忽然发现,使用如下的SQL是无法查询到对应column为null的数据的: select * from test where name != 'Lewis'; ...
- Kotlin, Android的Swift
Kotlin, Android的Swift 苹果已经用Swift代替Objective-C,一种古老的语言,来进行iOS的开发了.明显Android开发也有这个趋势. 虽然现在已经可以选择Scala或 ...
随机推荐
- 【洛谷P2426】删数
删数 题目链接 一道裸的区间DP,f[l][r]表示剩下区间[l,r]时的最大价值 可以由f[1~l-1][r]和f[l][r+1~n]转移过来 详见代码: #include<algorithm ...
- 学大伟业 Day 2 培训总结
一.dp 动态规划的本质 是一种思想.通过对原问题划分成子问题,寻找子问题之间的联系,通过求解子问题得出原问题的解.与贪心不同的是,动归是深谋远虑,考虑全局最优解:而贪心则目光短浅,只考虑局部最优解. ...
- 促销规则 promotion rule
参考:http://www.cnblogs.com/winstonyan/archive/2012/10/29/b2c_research_promotion_engine_and_rule_1.htm ...
- SqlSugar批量添加修改问题
直接InsertRange空集合会报错,如果我们是同时执行多个添加或修改,不要共用一个上下文,最好是在方法里面声明上下文进行区分,不然容易报错 //如果同时执行多个添加,更新 操作不要共用一个上下文, ...
- etcd部署简单说明
etcd是一个K/V分布式存储,每个节点都保存完成的一份数据.有点类似redis.但是etcd不是数据库. 1.先说废话.之所以会用etcd,并不是实际项目需要,而是前面自己写的上传的DBCacheS ...
- 使用php+gmail 发送邮件
<?php namespace app\index\controller; use think\Controller; use PHPMailer\PHPMailer; class Test e ...
- 你的sql查询为什么这么慢?
做后台开发的程序猿通常需要写各种各样的sql,可很多时候写出来的sql虽然能满足功能性需求,性能上却不尽人意.如果业务复杂,表结构和索引设计又不合理的话,写出来的sql执行时间可能会达到几十甚至上百秒 ...
- windows下openresty中使用lua做接口转发、二次封装等
需求:根据客户需求,可以在ngx下 通过lua做接口二次封装再次转发给用户或第三方 场景:对返回值有要求的.接口屏蔽字段.或做一些业务上的验证等 1.windows直接下载openresty 解压即可 ...
- 爬虫——BeautifulSoup4解析器
BeautifulSoup用来解析HTML比较简单,API非常人性化,支持CSS选择器.Python标准库中的HTML解析器,也支持lxml的XML解析器. 其相较与正则而言,使用更加简单. 示例: ...
- 路由器基础配置之ppp封装下的pap,chap认证
我们将以上面的拓扑图完成本次实验,路由器的默认封装为HDLC,要求为把路由器全被更改为ppp封装,并在router3与router4之间用pap认证,在router4与router5之间用chap认证 ...