«instanceof» in Kotlin: Type Checking with is and when (Guide)

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

«instanceof» in Kotlin: why it's not Java, and how it makes code cleaner

\n\n

If you came to Kotlin from the world of Java, you are probably used to the keyword instanceof. It helps you find out if an object is an instance of a certain class. But in Kotlin, this operator does not exist. And this is not a bug, but a feature.

\n\n

Kotlin offers a much more elegant, safe, and concise way to check an object's type — the is operator. It not only answers the question "who are you?" but also automatically casts the object to the required type. This is called smart cast, and it's one of those features that make coding in Kotlin so enjoyable.

\n\n

In this guide, we will cover:

\n
    \n
  • How to use the is operator instead of instanceof;
  • \n
  • What a smart cast is and how it works;
  • \n
  • How to elegantly handle multiple types using when;
  • \n
  • How safe casting as? differs from regular as;
  • \n
  • And, of course, real code examples.
  • \n
\n\n

Let's go!

\n\n

1. The is operator — a direct analog of instanceof

\n\n

In Java you would write:

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

In Kotlin, the same thing looks like this:

\n
if (obj is String) {\n    println(obj.length) // Smart cast! obj is already String\n}
\n\n

Notice: after the obj is String check, you do not need to explicitly cast obj to type String. The Kotlin compiler knows that inside the if block, the variable obj is guaranteed to be a string. This is smart cast.

\n\n

How does it work under the hood?

\n

The compiler analyzes the execution flow. If it sees an is check and finds no possibility of the variable's type changing between the check and its use (for example, in multithreaded code or when modifying a var), it automatically casts the type. For val this always works, for var — only if the variable cannot be changed between the check and its use.

\n\n

2. Negation: !is

\n\n

Want to check that an object is not of a certain type? Use !is:

\n
if (obj !is String) {\n    println("This is not a string")\n} else {\n    // Here obj automatically became String\n    println("String length: ${obj.length}")\n}
\n\n

Convenient and readable, right?

\n\n

3. Multiple checks with when

\n\n

Now imagine you have an object that could be one of several types. In Java, you would write a chain of if-else if with instanceof. In Kotlin, there is a more elegant tool — the when construct.

\n\n
fun describe(obj: Any): String {\n    return when (obj) {\n        is String -> "String of length ${obj.length}"\n        is Int -> "Integer: $obj"\n        is List<*> -> "List of ${obj.size} elements"\n        is Map<*, *> -> "Map with ${obj.size} entries"\n        else -> "Unknown type"\n    }\n}\n\nfun main() {\n    println(describe("Hello"))   // String of length 5\n    println(describe(42))         // Integer: 42\n    println(describe(listOf(1,2)))// List of 2 elements\n}
\n\n

Notice: inside each when branch, smart cast also works! In the is String branch, the variable obj is already considered a string, and you can call obj.length without an additional cast.

\n\n

This is much more compact and safer than a classic switch or a chain of if statements.

\n\n

4. Safe casting: as?

\n\n

Sometimes you need not just to check the type, but to immediately get a value of a specific type. In Java, you would do (String) obj

Blogs

Book Recommendations