第六章 Kotlin的类型系统
6.1 可空性
现代编程语言包括Kotlin解决Java中空类型异常问题的方法是把运行时的错误转变成编译期的错误。通过支持作为类型系统的一部分的可空性,编译器就能在编译期发现很多潜在的错误,从而减少运行时抛出异常的可能性。
6.1.1 可空类型
Kotlin对可空类型是显式支持的,也就是意味着Kotlin程序对一个变量的类型是否可为空是有严格区分和判定的。
- 不可空类型:没有?标记的类型,所有常见类型默认都是非空的。
- 可空类型:类型名称后面加上问号。
- 不可空类型和可空类型是严格区分的,不可空类型可以赋值给可空类型,但可空类型不能赋值给不可空类型。
- 不可空类型不能存储null引用,可空类型同样不能调用正常不可空类型的方法。
- 可空类型最重要的操作就是和null进行比较,而且一旦进行了比较,编译器就会记住,并且在这次比较发生的作用域内把这个值当做非空类型来对待。
代码示例:
fun strLenSafe(s:String?):Int{
//没有比较前直接用s.length的话会报编译错误
if(s != null){
return s.length else 0
}
return 0
}
//调用
val x:String? = null
strLenSafe(x)
//"abc"是String类型
strLenSafe("abc")
>>>>>>
0
3
6.1.2 类型的含义
维基百科上很棒的描述:类型就是数据的分类,决定了该类型可能的值,以及该类型可以完成的操作。
按这个描述来看的话,Java的类型系统并不能很好地工作,很大原因在于null。
例如String类型的变量,可以是String的实例和null,但这两种值完全不一样,用instanceOf运算符也会表明null不是String。
Kotlin对此就是区分开可空类型和不可空类型,使得运算流程变得明朗。
Kotlin的可空类型并不是非空类型的包装,所有的检查发生在编译期,并不会在运行时带来额外开销。
6.1.3 安全调用运算符:?.
1.概念说明
?.运算符:把一次null检查和一次方法调用合并成一个操作。
2.示例
2.1 调用方法
//两种等同的使用
if(s!=null) s.toUpperCase() else null
s?.toUpperCase()
2.2调用属性
class Employ(val name:String,val manager:Employee?)
//调用
fun managerName(employee:Employee):String? = employee.manager?.name
2.3链式调用
val country = this.company?.address?.country
6.1.4 Elvis运算符:?:
1.概念说明
Elvis运算符(null合并运算符):?:,接受两个运算数,如果第一个运算数不为null,运算结果就是第一个运算数,否则运算结果就是第二个运算数。
特别地,第二个运算数可以是return或者throw表达式。
2.示例
//简单调用
val t:String = s ?: ""
//和?.一起使用
fun strLenSafe(s:String?):Int = s?.length ?: 0
//第二个运算数是throw表达式
val address = person.country?.address ?: throw IllegalArgumentException("No address")
6.1.5 安全转换:as?
1.概念说明
as?运算符:尝试把值转换成指定的类型,如果值不是合适的类型就返回null。
当检查过类型并拒绝了null值,智能转换就会生效
2.示例
//常见的equals方法
fun equals(o:Any?):Boolean{
val otherPerson = o as? Person ?: return false
//智能转换生效,不用再加?
return otherPerson.name == firstName
}

最低0.47元/天 解锁文章
962

被折叠的 条评论
为什么被折叠?



