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

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

is!is

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

kotlin 复制代码
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则会自动转成相应的类型,不需要再显示的进行类型转换了

kotlin 复制代码
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)
}
kotlin 复制代码
fun main() {
    val x : Any = ""
    if (x !is String || x.length == 0) return

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

when中使用

kotlin 复制代码
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进行操作

kotlin 复制代码
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风险,需要添加?

kotlin 复制代码
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

kotlin 复制代码
fun main() {
    val str: Any? = null
    val s = str as? String
    println(s)  // null
}
相关推荐
Haha_bj1 天前
七、Kotlin——扩展(Extensions)
android·kotlin
urkay-1 天前
Android getDrawingCache 过时废弃
android·java·开发语言·kotlin·iphone·androidx
用户69371750013841 天前
24.Kotlin 继承:调用超类实现 (super)
android·后端·kotlin
alexhilton1 天前
借助RemoteCompose开发动态化页面
android·kotlin·android jetpack
QING6182 天前
Jetpack Compose Brush API 简单使用实战 —— 新手指南
android·kotlin·android jetpack
QING6182 天前
Jetpack Compose Brush API 详解 —— 新手指南
android·kotlin·android jetpack
鹿里噜哩2 天前
Spring Authorization Server 打造认证中心(二)自定义数据库表
spring boot·后端·kotlin
用户69371750013842 天前
23.Kotlin 继承:继承的细节:覆盖方法与属性
android·后端·kotlin
Haha_bj2 天前
五、Kotlin——条件控制、循环控制
android·kotlin