在 Kotlin 中,操作符 as 用于显式类型转换(cast)。有两种变体:as 和 as?。前者会抛出异常,后者则更安全。这个工具对于处理多态性以及数据迁移和与外部 API 的交互非常重要。
在 Java 中,类型转换使用 cast 操作符 (TargetType)obj,当出现错误时会抛出 ClassCastException。Kotlin 扩展了这一概念,添加了安全 cast (as?),这使得管理 nullability 和运行时错误更加方便和清晰。
在大型项目中,强制类型转换是危险的:如果类型不匹配,程序会崩溃(ClassCastException)。需要最小化这种行为,避免静默错误或 NPE。重要的是要清晰地区分应该处理错误的情况和可以安全返回 null 的情况。
Kotlin 提供了两个操作符:
as:强制类型转换,如果类型不匹配则抛出 ClassCastException。as?:安全类型转换 — 如果转换不可能则返回 null。val x: Any = "Hello, Kotlin!" val s1: String = x as String // Ok, x 是 String val s2: String? = x as? String // Ok, x 是 String val n: Int? = x as? Int // n = null, 安全 cast
as 在出错时会抛出 ClassCastException。as? 返回 null,最小化崩溃错误。'as' 是否总是检查运行时类型?
是的,如果 cast 发生在不兼容的类型上,将会产生 ClassCastException。然而,对于某些隐式转换,例如在 Int 和 Float 之间,没有这种转换 — Kotlin 通过方法(toInt, toFloat)进行习惯性转换。
可以用 'as' 将可空类型转换为非空类型吗?
可以,但要小心:如果值为 null,将会抛出异常。任何将可空类型转换为非空类型的操作,在未经检查的情况下都可能导致运行时错误。
val x: String? = null val y: String = x as String // 将抛出 ClassCastException!
'is' 和 'as' 有什么区别?
'is' 是类型检查操作符。返回 true/false,而不进行类型转换。'as' 进行类型转换,如果不可能则抛出异常(或者在使用 'as?' 时返回 null)。它们通常一起使用以安全地进行转换:
if (x is String) { val s: String = x // 智能转换 }
as,导致 ClassCastException。在数据解析模块中,所有对象都通过 as 解析,例如 obj as Double。如果数据错误,应用程序将因 ClassCastException 而崩溃。
优点:
缺点:
使用智能转换(通过 is)或安全转换(as?):
val price = (obj as? Double) ?: 0.0
优点:
缺点: