Kotlin笔记11-类型检查和转换'is' and 'as'

在运行时可以通过 is!is 来检测一对象的类型。

智能的类型转换 Smart Casts

在很多情况下,我们不需要在kotlin中显示地使用类型转换操作,因为编译器会追踪 is 检查和显示的类型转换,并会自动为不可变类型的值进行类型转换,如:

fun demo(x: Any) {
    if (x is String) {
        print(x.length) // x is automatically cast to String
    }
}

当相反的类型检查失败时,编译器能很智能地进行一个安全的类型转换,如:

if (x !is String) return
    print(x.length) // x is automatically cast to String

或者在使用 &&|| 时,编译器也会智能地推断类型,如:

// 在 `||` 右侧, x 被智能地转换成 String 类型
    if (x !is String || x.length == 0) return

    // 在 `&&` 右侧, X 被智能地转换成 String 类型
    if (x is String && x.length > 0) {
        print(x.length) // x is automatically cast to String
    }

when 表达式和 while循环中,这类智能转换同样适用,如:

when (x) {
    is Int -> print(x + 1)
    is String -> print(x.length + 1)
    is IntArray -> print(x.sum())
}

 

类型不安全的转换符 as 和 类型安全转换符 as? 

如果待转变量在不确定其类型是否为指定类型时,会抛出异常,如下面代码中,如果变量 y 是null,就会抛出异常:

val x: String = y as String

为了符合Java的类型转换语法,使用可空类型来处理,如:

val x: String? = y as String?

为了避免在类型转换时抛出异常,可以使用安全的转换符 as?,  在转换失败时,尽管as?后面的类型是非空的,也可以返回null:

val x: String? = y as? String

 

类型擦除和范型类型检查

Kotlin在编译时确保涉及泛型的操作的类型安全性,而在运行时,泛型类型的实例不保存有关其实际类型参数的信息。 例如,List <Foo>被擦除为List <*>。 通常,无法在运行时检查实例是否属于具有某些类型参数的泛型类型。

鉴于此,编译器禁止由于类型擦除而无法在运行时执行的is-checks,例如“ints is List<Int>”或“list is T”(类型参数)。 但是,您可以针对星型投影类型检查实例:

if (something is List<*>) {
    something.forEach { println(it) } //  items被当作是 `Any?`类型
}

类似地,当您已经静态检查实例的类型参数(在编译时)时,您可以进行is-check或者涉及该类型的非泛型部分的强制转换。 请注意,在这种情况下省略尖括号:

fun handleStrings(list: List<String>) {
    if (list is ArrayList) {
        // `list` 被智能地转换成 `ArrayList<String>`
    }
}

带有省略类型参数的相同语法可用于不考虑类型参数的强制类型转换:“list as ArrayList”

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值