作者:Antonio Leiva

时间: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)的更多相关文章

  1. 优雅的运用 Kotlin 的 null safety 特性,而不要简单的直接用 !!双感叹号

    对于 Null 的检查是 Kotlin 的特点之一.强制你在编码过程中考虑变量是否可为 null,因此可以避免很多在 Java 中隐藏的 NullPointerException. 但是,当你用插件直 ...

  2. java里null强转为某个类会报错吗?

    1.定义一个User类如下: /** * @author lizhibiao * @date 2018/11/27 17:21 */public class User{ private String ...

  3. kotlin之null值安全性

    var a: String =null // 编译错误 var a: String? =null // 编译通过 要允许null值, 需要将变量声明为可为null的字符串类型:String? fun ...

  4. MySQL里null与空值的辨析

    CREATE TABLE `test` ( `col1` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `co ...

  5. 用Kotlin实现Android定制视图(KAD 06)

    作者:Antonio Leiva 时间:Dec 27, 2016 原文链接:https://antonioleiva.com/custom-views-android-kotlin/ 在我们阅读有关c ...

  6. 在Kotlin编写RecyclerView适配器(KAD 16)

    作者:Antonio Leiva 时间:Mar 14, 2017 原文链接:https://antonioleiva.com/recyclerview-adapter-kotlin/ 通过创建Recy ...

  7. 尝试Java,从入门到Kotlin(下)

    上篇已提(tu)到(cao)Java中的各种坑.习惯了C#的各种特性和语法糖后,再转到Java感觉比较别扭.最后本着反正Java也不是很熟悉,干脆再折腾折腾其他语言的破罐子破摔的心态,逛了一圈JVM语 ...

  8. SQL - where条件里的!=会过滤值为null的数据

    !=会过滤值为null的数据 在测试数据时忽然发现,使用如下的SQL是无法查询到对应column为null的数据的: select * from test where name != 'Lewis'; ...

  9. Kotlin, Android的Swift

    Kotlin, Android的Swift 苹果已经用Swift代替Objective-C,一种古老的语言,来进行iOS的开发了.明显Android开发也有这个趋势. 虽然现在已经可以选择Scala或 ...

随机推荐

  1. 2018.10.6 Hibernate配置文件详解-------ORM元数据配置 &&& hibernate主配置文件

    ORM既然是实体与关系数据库的映射,那就需要建立实体和关系数据库之间的基础数据,也可以称为元数据.简单的说就是表示类与表.列与属性(get.set方法)等等之间对应关系的数据. Customer.hb ...

  2. public /protected/private的作用域

    作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × ×

  3. EF Ccore 主从配置 最简化

    业务需要 配置一主多从数据库 读写分离  orm用的ef core , 把思路和代码写下 1. 配置2个数据库上下文 ETMasterContext  ETSlaveContext(把增删改功能禁用掉 ...

  4. js事件委托代码优化【感悟总结】

    前两天接手了同事的一个项目,是一个网站首页,其中有段代码很累赘,要实现的功能就是, 通过给父元素添加鼠标移入移出事件,来控制子元素显示隐藏. html代码,一共有四个父元素div,每个父元素嵌套一个子 ...

  5. RabbitMQ消息中间件极速入门与实战

    1:初识RabbitMQ RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于AM ...

  6. 【PTA 天梯赛】L2-016. 愿天下有情人都是失散多年的兄妹(深搜)

    呵呵.大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人.父母.祖父母.曾祖父母.高祖父母)则不可通婚.本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚? 输入格式: 输入 ...

  7. Vmware+CentOs7+共享目录

    首先下载VMware和CentOs7的镜像 安装VMware我是参考的https://www.cnblogs.com/wuyx/p/7246675.html,已经非常详细了 然后需要配置网络了 参考 ...

  8. Spring Boot多环境配置

    在项目开发阶段,开发环境和实际生产环境是不一样,比如使用的数据库/服务连接配置等.因此,配置多个开发环境profile还是必要的 多环境的配置(yml)方式 配置其实很简单,在resource目录下, ...

  9. centos7中vsftp的搭建

    开启vsftpd:service vsftpd start关闭vsftp:service vsftpd stop 安装vsftpd: yum -y install vsftpd 建立vsftpd帐号: ...

  10. jquery添加html代码的几种方法

    经常用jq来DOM添加html代码 就总结了jq里面最常用的动态添加html代码的方法 append在元素内部的尾部加上元素 prepend在元素内部的前部加上元素 after在元素外部的尾部加上元素 ...