8:kotlin 类型检查和转换(Type checks and casts)

在运行时可以执行类型检查以检查对象的类型。类型转换将对象强制转换为不同的类型

is!is

可以使用is或者!is来判断实例是不是指定的类型

fun main() {
    var obj : Any = "cast"
    if (obj is String) {
        println(obj.length)   // 4
    }

    obj = 123
    if (obj !is String) { 
        print("Not a String") // Not a String
    } else {
        println(obj.length)
    }
}

智能转换

正常情况下,当使用了is或者!is判断实例类型时,如果返回的是true则会自动转成相应的类型,不需要再显示的进行类型转换了

fun main() {
    var obj : Any = "cast"
    if (obj is String) {
        println(obj.length)   // 4
    }
//    println(obj.length)   // 报错 - Unresolved reference: length
    
    if (obj !is String) return
    println(obj.length)
}
fun main() {
    val x : Any = ""
    if (x !is String || x.length == 0) return

    if (x is String && x.length > 0) {
        print(x.length) 
    }
}

when中使用

when (x) {
    is Int -> print(x + 1)
    is String -> print(x.length + 1)
    is IntArray -> print(x.sum())
}

注意,只有当编译器能够保证变量在检查和使用之间不会改变时,智能强制转换才会起作用。

只能转换在一下场景生效

变量类型 说明
var 本地变量 一般都会生效,除了局部委托变量
var 类属性 如果属性是私有的、内部的,或者检查是在声明属性的同一模块中进行的,那么可以使用智能转换。但是,智能转换不能用于开放属性或具有自定义 getter 的属性。
val本地变量 如果变量在检查和使用之间没有被修改,没有被修改它的 lambda 捕获,也不是本地委托属性,那么就可以使用这个变量。
val类属性 永远不会,因为变量可以在任何时候被其他代码修改。

不安全的强制转换

不安全的强制转换通常会报错,使用as进行操作

fun main() {
    val str: Any = "cast"
    val s = str as String

    val i = str as Int  //报错 java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer
}

注意,不能使null转换成String类型,如果有null风险,需要添加?

fun main() {
    val str: Any? = null
    val s1 = str as String?
    val s2 = str as String   // 报错 - java.lang.NullPointerException: null cannot be cast to non-null type kotlin.String
}

安全的强制转换

如果要避免异常,可以使用as?,如果转换失败则返回null

fun main() {
    val str: Any? = null
    val s = str as? String
    println(s)  // null
}

你可能感兴趣的:(kotlin教程,kotlin)