is和!is操作符
我们可以通过is操作符和!is操作符来检查一个对象是否是目标类型:
if (obj is String) {
    print(obj.length)
}
if (obj !is String) { // same as !(obj is String)
    print("Not a String")
}
else {
    print(obj.length)
}
职能转换(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 is automatically cast to string on the right-hand side of `||`
    if (x !is String || x.length == 0) return
    // x is automatically cast to string on the right-hand side of `&&`
    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())
}
注意:当编译器不能保证变量在检查和使用之间不会发生改变的时候,职能转换则是不能用的。也就是说,智能转换的使用需要依据以下规则:
- val局部变量,总是可以。
 - val属性:若属性是
private或internal类型的,或者类型检查是执行在属性声明的同一模块中的,则可以使用智能转换。智能转换不能用于open属性或者具有自定义getter的属性。 - var局部变量:如果变量在检查和使用之间没有修改,且没有被毁修改它的λ表达式捕获,则可以使用。
 - var属性:总是不可以。(因为该变量的值可以在任意时刻被任意代码修改)
 
非安全转换操作("Unsafe" cast operator)
通常,如果一个转换不能够完成的话讲抛出一个异常。因此,我们称之为非安全的。这种非安全的转换在Kotlin中通过中缀操作符as实现:
val x: String = y as String
注意:null不能被转换为String,因为该类型是不能为null的。也就是说,如果变量y是null,则上述代码将会抛异常。为了匹配Java转换语义,在转换右边必须是可null类型:
val x: String? = y as String?
安全转换操作("Safe" (nullable) cast operator)
为了避免异常的抛出,可以使用安全转换操作符as?,当转换失败的时候,将会返回null
val x: String? = y as? String
注意:尽管as?右侧是一个非null类型String,但其转换结果则可以是null。