Kotlin从入门到进阶实战
上QQ阅读APP看书,第一时间看更新

3.5 类型检测与类型转换

Kotlin在运行时通过使用is操作符或其否定形式!is来检查对象是否符合给定类型。在一般情况下,不需要在Kotlin中使用显式转换操作符,因为编译器跟踪不可变值的is检查,并在需要时自动插入(安全的)转换。下面分别具体介绍。

3.5.1 is运算符

is运算符可以检查对象A是否与特定的类型X兼容(此对象A是X类型或者派生于X类型),还可以用来检查一个对象(变量)是否属于某数据类型(如Int、String、Boolean等)。C#里面也有is运算符。

is运算符类似Java中的instanceof:

在Kotlin中,我们可以在运行时通过使用is运算符或其否定形式!is,来检查对象是否符合给定类型:

    >>> "abc" is String
    true
    >>> "abc" !is String
    false
    >>> null is Any
    false
    >>> null is Any?
    true

代码示例如下:

    @RunWith(JUnit4::class)
    class ISTest {
        @Test fun testIS() {
            val foo = Foo()
            val goo = Goo()
            println(foo is Foo) //true
            println(goo is Foo) //子类is父类=true
            println(foo is Goo) //父类is子类=false
            println(goo is Goo) //true
        }
    }
    open class Foo
    class Goo : Foo()

3.5.2 类型自动转换

在Java代码中,当我们使用str instanceof String来判断其值为true的时候,我们想使用str变量,还需要显式地强制转换类型:

而大多数情况下不需要在Kotlin中使用显式转换操作符,因为编译器会跟踪不可变值的is检查,并在需要时自动插入(安全的)转换:

3.5.3 as运算符

as运算符用于执行引用类型的显式类型转换。如果要转换的类型与指定的类型兼容,转换就会成功进行;如果类型不兼容,使用as?运算符就会返回null。

代码示例如下:

可以看出,在Kotlin中,父类是禁止转换为子类型的。

按照Liskov替换原则,父类转换为子类是对OOP的严重违反,因为子类除了包含父类所有的方法和属性之外,还可以自定义成员方法与属性,而父类则未必具有和子类同样的成员,所以这种转换是不允许的。