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?** ‌:安全转换的推荐方式,避免异常。
相关推荐
王码码20351 分钟前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥17 分钟前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓28 分钟前
[JDBC]元数据
android
独行soc39 分钟前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能1 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿1 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc1 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20352 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106322 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview
vistaup2 小时前
OKHTTP 默认构建包含 android 4.4 的TLS 1.2 以及设备时间不对兼容
android·okhttp