一、类型系统
参考《Kotlin从入门到进阶实战》41页
二、可空类型
参考《Kotlin从入门到进阶实战》45页
三、安全操作符
kotlin是空安全的。因为我们需要通过一个可空类型符号"T?”来明确地指定一个对象类型T是否能为空。
1、安全调用符“?”
用“?”修饰,表示成员可空。
// 字符串可空
var str:String? = null
println("str len = " + str?.length)
// 输出
System.out: str len = null
str = "abcd"
println("2 str len = " + str.length)
// 输出
I/System.out: 2 str len = 4
2、非空断言“!!”
kotlin中提供了断言操作符“!!”,使得可空类型对象可以调用成员方法或者属性(但遇见null,就会导致空指针异常,程序崩溃)
// 字符串可空
var str:String? = null
println("str len = " + str!!.length)
// 输出报错:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.htkj.flowtest/com.htkj.flowtest.MainActivity}: java.lang.NullPointerException.
3、Elvis运算符“?:”
使用Elivis操作符“?:”来给定一个在null情况下的替代值
// 字符串可空
var str:String? = null
str = str ?: "NULL11" // 当str 为null时,str为默认值“NULL11”
println("str len = " + str!!.length)
// 输出
I/System.out: str len = 6
// 字符串可空
var str:String? = "12345678"
str = str ?: "NULL11" // 当str 不为null时,str为原来值
println("str len = " + str!!.length)
// 输出
I/System.out: str len = 8
四:特殊类型
1、Unit类型
kotlin中的Unit类型实现了与Java中的void一样的功能。定义如下:
public object Unit {
override fun toString() = "kotlin.Unit"
}
不同的是,当一个函数没有返回值的时候,我们用Unit来表示这个特征,而不是null。大多数时候,我们并不需要显示地返回Unit,或者声明一个函数的返回类型为Unit,编译器会推断出它。例如:
fun testVoid() {
println("return is null")
}
// 调用
println("打印返回值 : " + testVoid())
// 输出
I/System.out: return is null
I/System.out: 打印返回值 : kotlin.Unit
跟其他类型一样,Kotlin.Unit父类型是Any。如果是一个可空的Unit?,那么父类型是Any? 。
2、Nothing 与 Nothing? 类型
在java中,void不能是变量的类型,也不能作为值打印输出。但是在Java中有个包装类Void是void的自动装箱类型。如果你想让一个方法的返回类型永远是null的话,可以把返回类型置为Void。这个Void对应Kotlin中的Nothing?,其唯一可悲访问的返回值也是null。
Nothing类的定义如下:
// Nothing的构造函数是private的,外界无法创建Nothing对象,这个Nothing()不能被实例化
public class Nothing private constructor()
从上面截图代码中可以看出Nothing()不可被访问。如果一个函数的返回值是Nothing,就意味着这个函数永远不会有返回值。
注意: Unit 与Nothing之间的区别是,Unit类型表达式计算结果的返回类型是Unit;Nothing类型的表达式计算结果是永远不会返回的(与Java中的void相同)
3、Any与Any?类型
Any是非空类型层次结构根;Any?是可空类型层次的根。Any?是Any的超集。
五:类型检测与类型转换
Kontlin在运行时通过使用is操作符或其否定形式!is来检查对象是否符合给定类型。在一般情况下,不需要在kotlin中使用显式转换操作符,因为编译器跟踪不可变值得is检查,并在需要时自动插入(安全)转换。
1、is运算符
is运算符可以检查对象A是否与特定的类型X兼容(此对象A是X类型或者派生X类型),还可以用来检查一个对象(变量)是否属于某数据类型(如Int ,String 等)。is运算符类似于java的instanceof。
println("null is Any " + (null is Any) )
println("null is Any? " + (null is Any? ))
// 输出
I/System.out: null is Any false
I/System.out: null is Any? true
2、类型自动转换
在java中,当使用str instanceof String 来判断其值为true的时候,我们想使用str变量,还需要显示地强制转换类型。而大多数情况下不需要在kotlin中使用显示转换操作符,因为编译器会跟踪不可变值得is检查,并需要时自动插入(安全的)转换。
3、as运算符
as运算符用于执行引用类型的显示类型转换。如果要转换的类型与指定的类型兼容,转换就会成功进行;如果类型不兼容,使用as?运算符就会返回null。在kotlin中 ,父类是禁止转换为子类型的。