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
}
相关推荐
进击的cc4 小时前
Android Kotlin:扩展函数如何优雅封装Android API
android·kotlin
进击的cc5 小时前
Android Kotlin:空安全机制在Android中的实战应用
android·kotlin
海盐芝士不加糖9 小时前
我又又又辞职了,然后做了一款“离线版微信”
kotlin·app·android jetpack
Kapaseker10 小时前
你知道屏幕上存在多少个 Window 吗
android·kotlin
stevenzqzq1 天前
Kotlin 进阶指南:中缀函数 (Infix Function)
android·kotlin·compose
Kapaseker1 天前
Android Studio 是如何预览 Compose 的
android·kotlin
__Yvan2 天前
Kotlin 的 ?.let{} ?: run{} 真的等价于 if-else 吗?
android·开发语言·前端·kotlin
tangweiguo030519872 天前
Android WorkManager 完整实战教程(含完整文件)
android·kotlin
顾道长生'2 天前
(Arxiv-2026)HiAR:基于分层去噪的高效自回归长视频生成
回归·kotlin·音视频·长视频生成
Kapaseker2 天前
Compose 中 CompositionLocalProvider 到底是干啥的
android·kotlin