ZetCode

Kotlin typeof 关键字

最后修改于 2025 年 4 月 19 日

Kotlin 的类型检查系统提供了强大的运行时类型检查工具。typeof 功能是反射和类型相关操作的关键。本教程通过实际示例深入探讨类型检查。

基本定义

Kotlin 没有像某些语言那样的直接的 typeof 关键字。相反,它使用 ::class 进行类型引用,使用 is 进行类型检查。它们提供了与其他语言中 typeof 类似的功能。

使用 ::class 获取类型

::class 语法获取表示类型的 KClass 对象。这相当于 Kotlin 中其他语言的 typeof 操作。

GetType.kt
package com.zetcode

fun main() {

    val str = "Hello Kotlin"
    val type = str::class
    
    println("Type: ${type.simpleName}") // Output: Type: String
    println("Qualified name: ${type.qualifiedName}") // Output: kotlin.String
}

在这里,我们使用 ::class 获取 String 的 KClass 对象。然后,我们打印类型的简单名称和限定名称。这展示了基本的类型自省。

使用 is 检查类型

is 运算符检查一个对象是否为特定类型。这是 Kotlin 执行运行时类型检查的主要方式。

TypeCheck.kt
package com.zetcode

fun checkType(obj: Any) {
    when (obj) {
        is String -> println("It's a String: ${obj.length} chars")
        is Int -> println("It's an Int: ${obj + 10}")
        else -> println("Unknown type")
    }
}

fun main() {

    checkType("Kotlin") // Output: It's a String: 6 chars
    checkType(42) // Output: It's an Int: 52
    checkType(3.14) // Output: Unknown type
}

此示例演示了在 when 表达式中使用 is 进行类型检查。每个分支处理不同的类型,展示了 Kotlin 的智能类型转换功能。

Java Class 与 Kotlin KClass

Kotlin 区分 Java 的 Class 和 Kotlin 的 KClass。您可以使用 .java.kotlin 属性在它们之间进行转换。

JavaKotlinClass.kt
package com.zetcode

fun main() {

    val kClass = String::class
    val jClass = kClass.java
    
    println("Kotlin class: $kClass")
    println("Java class: $jClass")
    
    val backToKClass = jClass.kotlin
    println("Back to KClass: $backToKClass")
}

这显示了 Kotlin 的 KClass 和 Java 的 Class 之间的关系。我们在它们之间进行转换,同时保留相同的类型信息。这对于互操作性很有用。

泛型中的类型检查

对于泛型,由于类型擦除,类型检查变得更加复杂。具体化的类型参数可以帮助在运行时维护类型信息。

GenericTypeCheck.kt
package com.zetcode

inline fun <reified T> checkType(obj: Any) {
    if (obj is T) {
        println("Object is of type ${T::class.simpleName}")
    } else {
        println("Object is NOT of type ${T::class.simpleName}")
    }
}

fun main() {

    checkType<String>("Kotlin") // Output: Object is of type String
    checkType<Int>("Kotlin") // Output: Object is NOT of type Int
}

此示例使用具体化的泛型函数来执行类型检查。具体化的类型参数保留了运行时类型信息,从而能够进行正确的类型检查。

使用 KClass 进行反射

KClass 提供了与其他语言中的 typeof 类似的反射功能。您可以检查属性、函数和其他类型信息。

ReflectionExample.kt
package com.zetcode

class Person(val name: String, val age: Int)

fun main() {

    val personClass = Person::class
    
    println("Properties:")
    personClass.memberProperties.forEach {
        println("- ${it.name}: ${it.returnType}")
    }
    
    println("\nConstructors:")
    personClass.constructors.forEach {
        println("- $it")
    }
}

这演示了使用 KClass 进行反射。我们检查一个类的属性和构造函数。这展示了 Kotlin 的类型自省功能的强大功能。

检查可空类型

类型检查适用于 Kotlin 中的可空类型。is 运算符会自动处理空值检查。

NullableTypeCheck.kt
package com.zetcode

fun checkNullableType(obj: Any?) {
    when (obj) {
        is String -> println("String: $obj")
        is Int -> println("Int: $obj")
        null -> println("Object is null")
        else -> println("Unknown type")
    }
}

fun main() {

    checkNullableType("Kotlin") // Output: String: Kotlin
    checkNullableType(42) // Output: Int: 42
    checkNullableType(null) // Output: Object is null
}

此示例显示了使用可空类型进行类型检查。is 检查正常工作,并且我们有一个单独的空值案例。这是惯用的 Kotlin。

比较类型

您可以比较 KClass 对象以检查两个对象是否属于同一类型。这对于高级类型检查场景很有用。

TypeComparison.kt
package com.zetcode

open class Animal
class Dog : Animal()

fun main() {

    val dog = Dog()
    val animal: Animal = dog
    
    println(dog::class == animal::class) // Output: true
    println(dog::class == Animal::class) // Output: false
    println(animal::class == Dog::class) // Output: true
}

这显示了使用 KClass 对象进行类型比较。请注意,即使分配给超类变量,运行时类型也会被保留。这对于准确的类型检查很重要。

类型检查的最佳实践

来源

Kotlin 反射文档

本教程深入探讨了 Kotlin 的类型检查功能,展示了在运行时检查和使用类型的各种方法。虽然 Kotlin 没有 typeof 关键字,但它的 ::classis 运算符提供了类似的功能,并具有额外的优势。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我撰写了 1400 多篇文章和 8 本电子书。我拥有超过八年的编程教学经验。

列出 所有 Kotlin 教程