Kotlin学习笔记5-8 其他-空安全
2018-02-10 17:07
399 查看
空安全
Kotlin官网:Other-Null Safety可空类型和不可空类型
Kotlin中将类型分为可空和不可空,以尽量避免空指针(NPE-NullPointerException)的问题。只有在如下情况下才会发生空指针异常:主动抛出
throw NullPointerException();
!!运算符;
被认为已经初始化,实际没有:
构造函数中将还未初始化完的this赋值给其他地方使用;
父类中使用了子类实现的成员,没有正确初始化;
和Java交互:
调用了Java中的null对象;
非空泛型被从Java中放入了null值;
其他Java中引起的空指针。
Kotlin中区分可空和不可空,例如一个不可空的String:
var a: String = "abc" a = null // 编译报错
要使用可空类型,声明为可空字符串
String?:
var b: String? = "abc" b = null // ok
此时调用不可空类型a的成员,Kotlin可以确保不会出现NPE,可以直接调用:
val l = a.length
如果访问可空类型b的成员,由于不保证非空,直接调用编译器会报错:
val l = b.length // error: variable 'b' can be null
非空检查
可以检查b是否为null,根据两种情况分别处理:val l = if (b != null) b.length else -1
更复杂的也可以:
if (b != null && b.length > 0) { print("String of length ${b.length}") } else { print("Empty string") }
这种检查后调用只有在b检查后不变才生效,例如一个局部变量,非空检查后立刻调用,或是一个只读的不能被重写的成员。这是因为如果是外部可更改的话,可能会在非空检查后被修改为空值。
安全调用
其次可以使用安全调用运算符?:
b?.length
在b不为null时返回b.length,为空是返回null,所以整个表达式的类型是Int?。
安全调用可以写成链式,链式调用的任意节点为空都会中断调用并返回null:
bob?.department?.head?.name
如果要在?调用中一次执行多步,可以用let函数:
val listWithNulls: List<String?> = listOf("A", null) for (item in listWithNulls) { item?.let { println(it) } // prints A and ignores null }
非空调用也可以写在赋值语句左侧,这样如果要赋值的链节中有空值则中断,表达式右侧不会被调用:
// If either `person` or `person.department` is null, the function is not called: person?.department?.head = managersPool.getManager()
Elvis运算符
假如有一个可空类型的引用r,希望在r不为空时使用,如果为空则使用默认值:val l: Int = if (b != null) b.length else -1
对于这种if表达式的形式,有更简便的Elivis运算符
?::
val l = b?.length ?: -1
对于Elvis运算符,如果
?:左侧的值不为null,则返回此值,如果为null则返回表达式右侧的值。
?:右侧表达式只在左侧表达式的值为null时才会执行。
Kotlin中
throw和
return都是表达式,可以用于Elvis运算符右侧:
fun foo(node: Node): String? { val parent = node.getParent() ?: return null val name = node.getName() ?: throw IllegalArgumentException("name expected") // ... }
!!
运算符
第三种处理方式针对惯用NPE的用户。非空断言运算符!!可以将任何类型转换成不可空类型,如果为空则抛出NPE:
val l = b!!.length
安全类型转换
类型转换如果转换目标类型不符会抛出ClassCastException。使用安全类型转换可以在转换失败时返回null值:
val aInt: Int? = a as? Int
可空类型集合
filterNotNull函数可以将可空类型集合的非空元素筛选成一个不可空类型集合:
val nullableList: List<Int?> = listOf(1, 2, null, 4) val intList: List<Int> = nullableList.filterNotNull()
相关文章推荐
- Kotlin学习笔记5-1 其他-解构声明
- Kotlin学习笔记5-2 其他-集合
- Kotlin学习笔记5-3 其他-区间
- 【安全牛学习笔记】WPS及其他工具
- 【安全牛学习笔记】其他途径
- 【安全牛学习笔记】WPS及其他工具
- Android知识体系梳理笔记五:Kotlin学习笔记二:空安全,操作符,Lambad表达式...
- Kotlin学习笔记5-4 其他-类型检查与转换
- Kotlin学习笔记5-5 其他-This表达式
- 【安全牛学习笔记】拒绝服务攻击工具-NMAP、匿名者拒绝服务工具包(匿名者发布的DoS工具)、其他拒绝服务工具-XOIC、HULK、DDOSIM、GoldenEye
- JAVA学习笔记47——其他容器简介4:guava之MulitiSet、MultiMap、BiMap、Table
- 黑马程序员_学习笔记:12) 其他API:java.lang.Runtime、java.util.Math、java.util.Date、java.util. Calendar
- windows api学习笔记-读写其他进程的内存
- java jvm学习笔记六(实现写自己的安全管理器)
- boost.asio 学习笔记06——其他
- 我的局域网安全学习笔记(一)
- 24.笔记 MySQL学习——其他存储引擎
- java SSL安全socket的通讯实例-java学习笔记(4)
- (学习笔记)数据的安全
- 【安全牛学习笔记】w3af-截断代理