Kotlin 的类型转换

在 Kotlin 中,类型转换和类型检查是处理对象类型安全的核心操作,主要通过 ‌**is‌(类型检查)和 ‌ as**‌(类型转换)两个操作符实现。以下是详细规则和示例:


一、类型检查操作符 is

作用 ‌:检查对象是否属于某个类型,返回 Boolean 值。

1. 基本用法

kotlin 复制代码
fun printLength(obj: Any) {
    if (obj is String) {
        // 此处 obj 自动智能转换为 String 类型
        println(obj.length)
    }
}

2. 智能转换(Smart Cast)

  • 当通过 is 检查类型后,Kotlin 编译器会自动将对象转换为目标类型(在作用域内)。
  • 适用场景 ‌:ifwhen 表达式或局部变量等不可变场景。
scss 复制代码
when (obj) {
    is Int -> println(obj + 1) // 自动转换为 Int
    is String -> println(obj.uppercase()) // 自动转换为 String
}

3. 反向检查 !is

kotlin 复制代码
if (obj !is Int) {
    println("Not an Int")
}

二、类型转换操作符 as

作用 ‌:将对象显式转换为目标类型。若类型不匹配,抛出 ClassCastException

1. 基本用法

rust 复制代码
val obj: Any = "Hello"
val str: String = obj as String // 显式转换为 String

显示转换 具有记忆功能,也就是智能类型转换,如下面案例:

kotlin 复制代码
open class Person3(private val name:String){
    fun showPersonName() = "父类的姓名是:$name"
    open fun printlnName() = println("$name")
    fun methodPerson() = println("我是父类的方法...") // 父类独有的函数
}

class Student3(private val subName:String):Person3(subName){
    fun showName() = "子类 的姓名是【${subName}】"
    override fun printlnName() = println(showName())
}

fun main(){
  val p:Person3  = Student3("张三")
    p.methodPerson()
    p.methodPerson()
    p.methodPerson()
}

运行结果如下

2. 安全转换 as?

  • 若转换失败,返回 null 而不是抛出异常。
  • 适用场景‌:不确定类型时,避免程序崩溃。
kotlin 复制代码
val num: Int? = "123" as? Int // num = null

三、关键区别与使用场景

操作符 行为 返回值 适用场景
is 检查类型是否匹配 Boolean 类型检查 + 智能转换
as 强制转换(可能抛出异常) 目标类型 确定类型匹配时的显式转换
as? 安全转换(失败返回 null 目标类型? 不确定类型时的安全转换

四、示例场景

1. 配合 when 使用智能转换

kotlin 复制代码
fun describe(obj: Any) = when (obj) {
    is Int -> "Int: $obj"
    is String -> "String: ${obj.length} chars"
    else -> "Unknown type"
}

2. 安全转换处理潜在风险

arduino 复制代码
val unknown: Any = 123
val text: String? = unknown as? String // 转换失败返回 null
println(text?.length ?: "Not a String")

3. 显式转换的异常处理

kotlin 复制代码
try {
    val num: Int = "ABC" as Int // 抛出 ClassCastException
} catch (e: ClassCastException) {
    println("Conversion failed")
}

五、注意事项

  1. ‌**避免滥用 as**‌

    显式转换可能引发运行时异常,优先使用 is 检查和智能转换。

  2. ‌**Any 类型的隐式转换**‌

    kotlin 复制代码
    val a: Any = 100
    if (a is Int) {
        val b: Int = a // 无需显式转换
    }
  3. 泛型类型的限制

    Kotlin 的泛型在运行时会被擦除,因此无法直接检查泛型类型:

    swift 复制代码
    // 以下代码无法通过编译
    if (list is List<String>) { ... }

案例

kotlin 复制代码
open class Person2(private val name: String) {

    fun showName() = "父类 的姓名是【$name】"
    // KT所有的函数,默认是final修饰的,不能被重写,和Java相反
    open fun myPrintln() = println(showName())
}

class Student2(private val subName: String) : Person2(subName) {
    fun showName2() = "子类 的姓名是【${subName}】"
    override fun myPrintln() = println(showName2())

}

// 1.普通运行子类输出
// 2.is Person Student File
// 3.is + as 转换
fun main() {
    val p: Person2 = Student2("王五")
    p.myPrintln()

    println(p is Person2)
    println(p is Student2)
    println(p is File)

    // is + as = 一般是配合一起使用
    if (p is Student2) {
        (p as Student2).myPrintln()
    }

    if (p is Person2) {
        // (p as Person2).myPrintln() // 因为子类重写了父类
        println((p as Person2).showName())
    }

六、总结

  • ‌**is**‌:用于安全类型检查,并触发智能转换。
  • ‌**as**‌:在确定类型时强制转换(风险较高)。
  • ‌**as?** ‌:安全转换的推荐方式,避免异常。
相关推荐
JhonKI3 小时前
【MySQL】存储引擎 - CSV详解
android·数据库·mysql
开开心心_Every4 小时前
手机隐私数据彻底删除工具:回收或弃用手机前防数据恢复
android·windows·python·搜索引擎·智能手机·pdf·音视频
大G哥4 小时前
Kotlin Lambda语法错误修复
android·java·开发语言·kotlin
鸿蒙布道师8 小时前
鸿蒙NEXT开发动画案例2
android·ios·华为·harmonyos·鸿蒙系统·arkui·huawei
androidwork8 小时前
Kotlin Android工程Mock数据方法总结
android·开发语言·kotlin
xiangxiongfly91510 小时前
Android setContentView()源码分析
android·setcontentview
人间有清欢11 小时前
Android开发补充内容
android·okhttp·rxjava·retrofit·hilt·jetpack compose
人间有清欢12 小时前
Android开发报错解决
android
每次的天空13 小时前
Android学习总结之kotlin协程面试篇
android·学习·kotlin
每次的天空15 小时前
Android学习总结之Binder篇
android·学习·binder