Kotlin !is 关键字
最后修改于 2025 年 4 月 19 日
Kotlin 的类型检查系统提供了强大的运算符来验证运行时的类型。!is 关键字用于负类型检查。本教程通过实际示例深入探讨了 !is 关键字。
基本定义
Kotlin 中的 !is 关键字是 is 运算符的否定形式。它检查一个对象是否不是特定类型的实例。与 is 一样,它在相应的代码块中启用智能类型转换。
基本 !is 检查
!is 最简单的用法是验证一个对象不是某种类型。当您想以不同的方式处理不同类型时,这很有用。
package com.zetcode
fun main() {
val obj: Any = 42
if (obj !is String) {
println("Object is not a String")
}
}
在这里,我们检查 obj 是否不是 String。由于它是一个 Int,因此条件为真,并打印消息。这是 !is 最基本的用法。
!is 与智能类型转换
在 !is 检查之后,Kotlin 将对象智能地类型转换为相应块中的否定类型。这使您可以安全地使用其他类型的方法。
package com.zetcode
fun printIfNotString(obj: Any) {
if (obj !is String) {
println("Value is ${obj} and type is ${obj.javaClass.simpleName}")
}
}
fun main() {
printIfNotString(123) // Output: Value is 123 and type is Integer
printIfNotString(true) // Output: Value is true and type is Boolean
}
在此示例中,在 !is String 检查之后,Kotlin 知道 obj 不是 String。然后,我们可以安全地访问实际类型的属性,例如 javaClass。
!is 在 When 表达式中
!is 运算符在 when 表达式中运行良好,以处理多种类型的情况。它有助于创建详尽的类型检查逻辑。
package com.zetcode
fun describeType(obj: Any): String {
return when (obj) {
is String -> "String of length ${obj.length}"
!is Number -> "Not a number"
else -> "Number with value ${obj.toDouble()}"
}
}
fun main() {
println(describeType("Hello")) // String of length 5
println(describeType(true)) // Not a number
println(describeType(42)) // Number with value 42.0
}
此示例显示了如何在 when 表达式中使用 !is。在 String 检查之后,!is Number 分支捕获所有非数字类型。
!is 与空值检查
!is 运算符可以与空值检查结合使用,以创建更复杂的条件。这在处理可空类型时特别有用。
package com.zetcode
fun processValue(value: Any?) {
if (value !is String? || value == null) {
println("Not a string or null")
} else {
println("String length is ${value.length}")
}
}
fun main() {
processValue(null) // Not a string or null
processValue(123) // Not a string or null
processValue("Kotlin") // String length is 6
}
在这里,我们将 !is 与空值检查结合使用,以处理非字符串类型和空值。智能类型转换确保我们可以在 else 分支中安全地访问 String 属性。
!is 在泛型函数中
!is 运算符可用于泛型函数,以对泛型参数执行类型检查。这需要具体化的类型参数。
package com.zetcode
inline fun <reified T> isNotType(obj: Any): Boolean {
return obj !is T
}
fun main() {
println(isNotType<String>("Hello")) // false
println(isNotType<Int>("World")) // true
println(isNotType<List<*>>(emptyList<String>())) // false
}
此泛型函数使用 !is 和具体化的类型参数来检查对象是否不是类型 T。具体化的参数在运行时保留类型信息。
!is 与集合
!is 运算符可用于检查集合类型或根据类型过滤集合。这在处理异构集合时很有用。
package com.zetcode
fun main() {
val mixedList: List<Any> = listOf(1, "two", 3.0, "four", 5)
val nonStrings = mixedList.filter { it !is String }
println("Non-string elements: $nonStrings")
if (mixedList !is List<String>) {
println("List contains non-string elements")
}
}
在这里,我们使用 !is 从混合列表中过滤掉 String 元素。我们还检查整个列表是否不是 List<String>。这两种用法都演示了 !is 与集合的使用。
!is 在类层次结构中
!is 运算符在处理类层次结构时特别有用。它有助于确定一个对象何时不是特定子类。
package com.zetcode
open class Animal
class Dog : Animal() {
fun bark() = "Woof!"
}
class Cat : Animal() {
fun meow() = "Meow!"
}
fun makeSound(animal: Animal) {
if (animal !is Dog) {
println("Not a dog")
if (animal is Cat) {
println(animal.meow())
}
} else {
println(animal.bark())
}
}
fun main() {
makeSound(Dog()) // Woof!
makeSound(Cat()) // Not a dog \n Meow!
}
此示例显示了类层次结构中的 !is。我们首先检查动物是否不是 Dog,然后处理其他情况。智能类型转换允许在适当的块中调用 Cat 特定的方法。
!is 运算符的最佳实践
- 与智能类型转换结合使用: 在
!is检查后利用 Kotlin 的智能类型转换,以获得更简洁的代码。 - 在 when 表达式中使用:
!is在when表达式中运行良好,用于详尽的类型检查。 - 考虑可空性: 在将
!is与可空类型一起使用时,请记住处理空值情况。 - 首选肯定检查: 有时,带 else 分支的
is比!is更清晰。 - 与具体化的泛型一起使用: 对于泛型函数,请将具体化的类型参数与
!is一起使用。
来源
本教程深入介绍了 Kotlin 的 !is 关键字,展示了它在各种场景中的用法,包括智能类型转换、when 表达式和泛型。如果使用得当,!is 运算符是用于类型安全的 Kotlin 代码的强大工具。
作者
列出 所有 Kotlin 教程。