Kotlin中的「instanceof」:使用is和when进行类型检查(指南)

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Kotlin中的「instanceof」:为什么它不是Java,以及它如何让代码更简洁

\n\n

如果您从Java世界来到Kotlin,您可能已经习惯了关键字instanceof。它有助于判断对象是否是某个特定类的实例。但在Kotlin中没有这个运算符。这不是一个缺陷,而是一个特性。

\n\n

Kotlin提供了一种更优雅、更安全、更简洁的方式来检查对象类型——is运算符。它不仅回答了「你是谁?」这个问题,还会自动将对象转换为所需的类型。这被称为智能转换(smart cast),它是让Kotlin代码如此令人愉悦的特性之一。

\n\n

在本指南中,我们将介绍:

\n
    \n
  • 如何使用is运算符代替instanceof;
  • \n
  • 什么是智能转换以及它是如何工作的;
  • \n
  • 如何使用when优雅地处理多种类型;
  • \n
  • 安全转换as?与普通转换as的区别;
  • \n
  • 当然,还有真实的代码示例。
  • \n
\n\n

让我们开始吧!

\n\n

1. is运算符——instanceof的直接替代

\n\n

在Java中,您会这样写:

\n
if (obj instanceof String) {\n    String str = (String) obj;\n    System.out.println(str.length());\n}
\n\n

在Kotlin中,同样的代码看起来是这样的:

\n
if (obj is String) {\n    println(obj.length) // 智能转换!obj已经是String类型\n}
\n\n

请注意:在检查obj is String之后,您不需要显式地将obj转换为String类型。Kotlin编译器自己知道,在if块内部,变量obj保证是字符串。这就是智能转换(smart cast)。

\n\n

它在底层是如何工作的?

\n

编译器会分析执行流程。如果它看到is检查,并且没有发现变量在检查和使用的过程中可能改变类型(例如,在多线程代码中或当变量是var时),它会自动转换类型。对于val,这总是有效的;对于var,仅当变量在检查和使用的过程中不会被修改时才有效。

\n\n

2. 否定:!is

\n\n

想要检查对象不属于某个类型?使用!is:

\n
if (obj !is String) {\n    println("这不是字符串")\n} else {\n    // 这里obj自动变成了String\n    println("字符串长度:${obj.length}")\n}
\n\n

方便且易读,对吧?

\n\n

3. 使用when进行多重检查

\n\n

现在想象一下,您有一个对象,它可能是多种类型之一。在Java中,您会写一串带有instanceof的if-else if。在Kotlin中,有一个更优雅的工具——when结构。

\n\n
fun describe(obj: Any): String {\n    return when (obj) {\n        is String -> "长度为${obj.length}的字符串"\n        is Int -> "整数:$obj"\n        is List<*> -> "包含${obj.size}个元素的列表"\n        is Map<*, *> -> "包含${obj.size}条记录的映射"\n        else -> "未知类型"\n    }\n}\n\nfun main() {\n    println(describe("你好"))   // 长度为2的字符串\n    println(describe(42))         // 整数:42\n    println(describe(listOf(1,2)))// 包含2个元素的列表\n}
\n\n

请注意:在每个when分支内部,智能转换同样有效!在is String分支中,变量obj已经被视为字符串,您可以直接调用obj.length而无需额外的转换。

\n\n

这比经典的switch或if链要紧凑和安全得多。

\n\n

4. 安全转换:as?

\n\n

有时您不仅需要检查类型,还需要立即获取特定类型的值。在Java中,您会使用(String) obj

博客

书籍推荐