我们使用kotlin难免遇到 ? ?. ?: !! as?等的用法,但是对于刚上手使用Kotlin知道它有针对Java NullPointerException的管理,而在Kotlin中?和!!均是和NullPointerException有关系,可他们的区别到底是什么呢?咱们详细了解一下。
? eg:String? 添加在类型后
image在kotlin中申明一个变量,如果类型后面不加?则不能直接给此变量赋值为null,在类型后面加上?就变成了可空类型,而可空类型可以直接赋值为null
private var msg: String? = null
private var msg1: String = ""
?. 表示当前对象可以为空
imagefun main(args: Array<String>) {
function1(null)
}
/**
* ?
*/
fun function1(msg: String?){
println(msg?.length)
}
结果输出
null
Process finished with exit code 0
我们都知道?
表示可以为空,具体原因是什么,请看如下Decompile代码
public final class KotlinNullKt {
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
function1((String)null);
}
public static final void function1(@Nullable String msg) {
Integer var1 = msg != null ? msg.length() : null;
boolean var2 = false;
System.out.println(var1);
}
看到这里我们明白了,当我们输了一个null值时,?
的作用就是判断当前的input是否为null,为null时返回null。这就是为什么我们看到输出null的原因了
!! 表示对象在不为空的情况下执行
image还是上边的代码,我们这次把println中的?.
修改为!!
输出结果立马变为我们熟悉的NPE
balabalabala
/**
* !!
*/
fun function1(msg: String?){
println(msg!!.length)
}
结果输出
Exception in thread "main" kotlin.KotlinNullPointerException
at com.eegets.leaks.KotlinNullKt.function1(KotlinNull.kt:18)
at com.eegets.leaks.KotlinNullKt.main(KotlinNull.kt:9)
Process finished with exit code 1
我们还是看Decompile代码
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
function1((String)null);
}
public static final void function1(@Nullable String msg) {
if (msg == null) {
Intrinsics.throwNpe();
}
int var1 = msg.length();
boolean var2 = false;
System.out.println(var1);
}
我们可以看到,此时当我输入了null
, 获取length变成了 msg.length
, 这样肯定会发生NPE
所以我们得到的结论是:!! 只有在我们刻意想让程序抛出NPE时才使用,解决问题的办法也就有两种:
- 将
!!
改为 ?. 保证输入可以为空 - 在调用
msg!!.length
之前加非空判断
网友评论