什么是Kotlin的空指针安全?

所谓的空指针安全,并不是说,在Kotlin领域不会再发生NullpointerException。而是说,Kotlin会尽可能的,将一些潜在的,可能发生NullpointerException的代码,在编译期就给阻断掉。在编译期,通过IDEA的语法检查工具,IDEA就能最大化的识别出,潜在的,可能发生NPE的代码,并报错和中断编译,来提醒开发者对相关代码进行修正。

举个Java的栗子

String test = "test";
test = null;
int length = test.length();

首先,这段代码明显是会抛出空指针异常,但是,IDEA在编译期,并不会报错,因为这是符合Java语法的。

为了避免空指针异常,我们可以这样改进代码:

String test = "test";
test = null;
int length =  0;
if(test != null){
  length = test.length();
}

但问题来了,这样做的话,代码会变得很冗长。

Kotlin为了解决这个问题,引进了空指针安全语法,具体是怎么做的,
让我们看下面的Kotlin版栗子

var test: String = "test"
test = null // complier gives you an error here
....

因为Kotlin语法的限制,到这里,编译器就会报错,你无法继续编译你的代码,因为语法不符。为什么不符?因为test被定义成为非空变量。如此一来,就避免了潜在的、可能的,会引起空指针异常的代码。又不需要if else来做检查,避免代码冗长,是否相当机智? Yes!

那么,问题就来了,那我非要给test设置一个null值,有毛有办法? 有。让我们接着看下面的栗子:

var test: String? = "test"
test = null // Ok
val length = test.length// complier gives you an error here

通过在变量类型后面加一个?问号,标识这个变量为**“可空变量”**。如此一来,就可以给变量赋值null。但问题来了,这样不就变成了Java版的普通类型了吗?不不不,因为,这个时候,如果你直接对一个可空变量进行引用时,编译器也不会让你的奸计得逞,放弃挣扎吧,骚年。

那要如何才能引用一个可空变量?有几种做法,有安全的,有不安全的。

我们先看不安全的:

var test: String? = "test"
test = null // Ok
val length = test!!.length// Ok, 强行调用,管他三七二十八,我就是要调用,空不空指针我不管。

只要在可空变量后面加两个!,就可以强行调用,编译器也没你的办法。编译器深暗一个道理,那就是与其反抗不了,不如好好享受。但结果是,你的程序可能会收到个空指针异常,然后闪退。

我们再来看,安全的做法:

var test: String? = "test"
test = null; // Ok
val length = if(test != null) test.length else 0 // Ok, 先判空,再使用,毛得问题

这种安全做法,就跟Java的冗长版没多大差别了。如果都必须这样做,那还怎么彰显,世界上最好的语言Kotlin的语法简洁?
接下来让我们,再看一种更native的,地道的Kotlin的做法:

var test: String? = "test"
test = null; // Ok
val length = test?.length ?: 0 // Ok, 如果test为null,则返回null。 如果test返回null, 则返回0.

test?.length,会先判断test是否为null?不是null,返回test.length,是null,返回 null。
对test?.length的返回值,执行 ?: 0 语句。一样,先判断这个返回值是不是null?
如果是null, 返回 ?: 后面的 0。如果不是null,则返回test.length的返回值。

简短的一句test?.length ?: 0代码,包含了两层if判断,岂不妙哉。是吧。

到此为止,我们已经学习了究竟什么是Kotlin的空指针安全,以及Kotlin是如何做到的。感谢各位的阅读,喜欢的麻烦点个赞,多谢。

Furthermore:

当混编Kotlin+Java时,编译期的空指针安全,会受到来着Java的代码的破坏,使用时,需要注意,详见这篇:
A trick about non-nullable type in kotln

你可能感兴趣的:(Kotlin,kotlin,kotlin空指针安全)