Kotlin Null安全性-Kotlin Nullable
在本教程中,我们将研究Kotlin Null安全性。
NullPointerException是任何程序员在其项目中目击的最常见的错误类型之一。
让我们看看Kotlin是如何处理的。
Kotlin Null安全
默认情况下,Kotlin编译器不允许任何类型在编译时将其值设置为null。
对于Kotlin,可空性是一种类型。
在较高的级别上,Kotlin类型适合两者之一。
- 可空性类型
- 不可为空类型
可空性作为一种类型
我们无法在Kotlin中定义以下语法。
var str: String = "theitroad Kotlin Archives" str= null //compilation error var a : String = null //compilation error.
要将类型设置为Nullable,我们需要在该类型后附加一个"?",如下所示。
var a : String? = null var newStr : String? = "Kotlin Null Safety" newStr = null
现在,每当我们访问一个Nullable Referernce时,我们都需要谨慎处理null情况。
注意:添加?将变量的类型从String更改为String ?,将Int更改为Int?等等。
最常见的方法是使用if else语句,如下所示。
if(a!=null) { print("The value of a is $a") } else{ print("Sorry a is null") }
现在,以上方法可以导致很多嵌套括号。
Kotlin确实提供了使用"安全调用"访问可空引用的更简单方法。
安全调用
要在变量上调用函数或者属性,通常需要执行以下操作。
var a : String = "Hello" print(a.length)
这不会始终与可空引用一起使用。
var a : String? = "Hi" print(a.length) //prints 2 a = null print(a.length) //compilation error
当Nullable引用包含空值时,不能使用点引用。
因此,Kotlin为我们提供了一个安全的调用运算符,可以在可空引用上使用,如下所示。
a = "Hi" print(a?.length) //prints 2 a = null print(a?.length) //prints null
安全调用"?。
"仅在值不为null时才执行相关调用。
否则,它将为您打印一个空值。
需要在多个变量上保留空性检查器时,安全调用非常方便,如下所示。
var streetName : String? = address?.locality?.street?.addressLine1
还有一种方法可以在可为空的引用上调用属性。
!!运算符
与安全调用相反,!!也称为非空断言,它将可空引用转换为其不可空类型,而不管它是否为空。
仅当您确定该值不为NULL时,才应使用此选项。
否则会导致NPE异常。
a = null println(a!!.length) //runtime error. a = "Hi" print(a!!.length) //prints 2
安全转换
?运算符也可以用于防止ClassCastException(另一个常见的异常)。
var b : String ="2" var x : Int? = b as? Int println(x) //prints null
在上面的代码中,我们可以安全地使用
as?
。
如果转换失败,则将该值设置为null,从而防止ClassCastException。
另一个例子:
var array1 : Array<Any?> = arrayOf("1","2","3") var i : Int? = array1[0] as? Int println(i) //prints null var s : String? = array1[0] as? String print(s) //prints 1
elvis运算符
到目前为止,只要安全调用运算符返回空值,我们就不会执行任何操作,而是输出空值。
elvis运算符 ?:
允许我们设置默认值,而不是null,如下所示。
var newString : String? = "theitroad.local" println(newString?.length) //prints 14 newString = null println(newString?.length?:"-1") //prints -1
elvis运算符等效于以下内容:
if(newString!null) { print(newString.length) } else{ print("-1") }
另一个示例:
var streetName : String? = address?.locality?.street?.addressLine1 ?: "Street Name not found"
使用let()
Let函数仅在引用不可为空时才执行指定的lamda函数,如下所示。
newString = " Kotlin from Android" newString?.let { println("The string value is: $it") } newString = null newString?.let { println("The string value is: $it") }
let中的语句是一个lamda表达式。
仅在newString的值不为null时运行。
它包含newString的非null值
使用Also()
除了也通常用于记录值之外,also
的行为与" let"相同。
不能将" it"的值分配给另一个变量。
这是let和一起更改的示例。
var c = "Hello" newString = " Kotlin from Android" newString?.let { c = it }.also { println("Logging the value: $it") }
注意:" let"中的语句不能放在"也"中。
反之亦然。
筛选出空值
我们可以使用以下函数从集合类型中过滤出Null值:
var array2: Array<Any?> = arrayOf("1", "2", "3", null) var newArray = array2.filterNotNull() println(newArray.size) //prints 3
Java互操作性
由于Java不会强迫您将类型声明为Nullable或者Non-Nullable类型,因此Kotlin编译器不会针对以下内容给出错误:
var javaObject = MyClass(null)
如果您设置Java注释@Nullable或者@NotNull,则Kotlin编译器会将其视为Nullable或者Not Nullable引用。