什么是Kotlin双爆炸(!!)运算符?


177

我正在使用Android Studio将Java转换为Kotlin。在实例变量之后,我得到了双响。什么是双重爆炸?更重要的是,这在哪里记录?

mMap!!.addMarker(MarkerOptions().position(london).title("Marker in London"))

Answers:


205

这是不安全的可为null的类型(T?)到非可为null的类型()的转换T, 如果值为!!则会抛出NullPointerException该异常null

在此与Kotlin的null-safety方法一起记录在案。


1
!!语句结束时是什么意思?IJ自动转换为Kotlin为我做到了val price = sale.latest!!
ycomp

7
@ycomp,表示sale.latest可以包含null; 仅当sale.latest不为null时,分配将成功,否则将抛出NPE。这提供了null安全性val price:其类型将为非null。参见kotlinlang.org/docs/reference/null-safety.html
热键

1
@hotkey:那么获取NPE和在空对象上访问最新方法之间有什么区别?
阿达

2
@Aada,调试NPE并遇到困难,很难找到将值设置为null的行/执行路径。此空作业可能在不同的上下文,课堂甚至一天中发生!通过使用,!!您可以快速失败并找到NPE的根本原因。我希望Java具有类似的功能(即没有丑陋的if声明和/或assert离子)。
卡斯卡德尔

82

这是使情况更清楚的示例。说你有这个功能

fun main(args: Array<String>) {
    var email: String
    email = null
    println(email)
}

这将产生以下编译错误。

Null can not be a value of a non-null type String

现在,您可以通过在String类型中添加问号使其可为空来防止这种情况。

所以我们有

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email)
}

这产生了一个结果

null

现在,如果我们希望函数在email值为null时引发异常,则可以在email末尾添加两个感叹号。像这样

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email!!)
}

这会抛出一个 KotlinNullPointerException


5
那么,为什么人们会使用“ !!” 即使不安全,因为当该变量为null时,应用程序将终止?
山姆

3
@david只有在您100%确定该变量不为空(例如,您明确检查了该变量)并且需要非空变量时才可以使用它
FMK

7
@FMK我明白了,谢谢!我知道使用Double bang可以使可为空的类型变量的值变为非可为空的类型变量,对吗?
山姆

2
@大卫是的,完全正确。
FMK

10

对于NullPointerException(或简称NPE)的粉丝,Double-bang运算符是一个绝佳选择。

不是空断言运营商 !!转换为任意值非空类型,如果值为null抛出异常。

val nonNull = a!!.length

因此,您可以编写a!!,这将返回非null值aString例如a),如果a为null,则抛出NPE 。

如果需要NPE,可以拥有它,但是必须明确要求它。在开发人员保证的情况下应使用此运算符-该值永远不会为null


2
作为初学者问:为什么要将任何值转换为非null类型?
Wolf359 '19

4
@ Wolf359它使您可以100%确保其值不为null。(“这是调试NPE,有一个很难定位是将值设置为空行/执行路径通病此空分配可能发生在不同的背景下,类甚至一天!”由Cascader)
减少活动
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.