Sitemap

Kotlin type checking and casting explained

3 min readJul 13, 2025
Press enter or click to view image in full size
Photo by Louis Tsai on Unsplash

Typecasting and Type Checking in Kotlin: A Comprehensive Guide

Kotlin is designed with modern language features that improve safety and expressiveness, and its approach to typecasting and type checking is no exception. In this blog, we’ll explore how Kotlin handles type conversions and type verification, covering concepts like smart casts, safe casts, and the use of the is, as, and as? operators.

1. What Is Type Checking in Kotlin?

Type checking is the process of verifying an object’s type at runtime. Kotlin uses the is operator to check if a variable is of a specific type. This operator returns a Boolean value and is similar to Java’s instanceof, but with a key difference: Kotlin supports smart casts.

Example:

fun printStringLength(value: Any) {
if (value is String) {
// Smart cast: 'value' is automatically cast to String in this branch.
println("Length of the string is ${value.length}")
} else {
println("Not a String")
}
}

In the code above, the compiler automatically “smart casts” the variable value to a String after checking with is, eliminating the need for explicit casts.

2. Typecasting: Converting Between Types

Typecasting is converting a variable from one type to another. In Kotlin, you use the as operator for casting. However, there are important differences between safe and unsafe casts:

  • Unsafe Cast (as):
  • The as operator casts a variable to a specified type. If the cast is not possible, it throws a ClassCastException.
  • Example:
val obj: Any = "Kotlin"
val str: String = obj as String // Works fine
  • If obj were not a String, the cast would throw an exception.
  • Safe Cast (as?):
  • The safe cast operator as? attempts to cast a variable to a specified type. If the cast isn’t possible, it returns null instead of throwing an exception.
  • Example:
val obj: Any = 123
val str: String? = obj as? String // Returns null, because obj is not a String
println(str) // Output: null

Safe casts are particularly useful when you’re not entirely sure about the type of an object, allowing you to handle casting failures gracefully.

3. Smart Casts: Kotlin’s Clever Type Inference

One of Kotlin’s standout features is smart casts. When you perform a type check using is, the compiler automatically casts the variable to the desired type within the scope where the check is true. This avoids repetitive and verbose explicit casts.

Example:

fun processInput(input: Any) {
if (input is List<*>) {
// Here, input is smart cast to List<*>
println("List size: ${input.size}")
} else {
println("Not a list")
}
}

Smart casts are safe and work in many scenarios, such as simple type checks within conditionals, making your code cleaner and reducing boilerplate.

4. Combining Type Checking and Typecasting

Often in Kotlin you might need to both check the type of an object and then use it as that type. Thanks to smart casts and safe casting, this is straightforward.

Example with Explicit Casting:

fun handleData(data: Any) {
if (data is String) {
// No explicit cast needed thanks to smart cast
println("String in uppercase: ${data.uppercase()}")
} else {
// Try a safe cast for an alternative type
val number: Int? = data as? Int
if (number != null) {
println("Number doubled: ${number * 2}")
} else {
println("Unsupported type")
}
}
}

Here, we check if data is a String to directly use its methods, and if not, we safely cast it to an Int to handle numeric operations.

5. Benefits and Best Practices

  • Safety First: Use smart casts to avoid unnecessary explicit casting, which makes your code safer and more concise.
  • Prefer Safe Casts: Use as? when there's any uncertainty about an object's type to prevent runtime exceptions.
  • Be Mindful of Nullability: Remember that safe casts return null on failure, so plan accordingly in your code logic.
  • Combine with Sealed Classes: Kotlin’s sealed classes, combined with smart casts, provide a robust mechanism for handling restricted class hierarchies, ensuring that every possible type is covered.

If you want to learn more about type checking and casting. Here is a video for you:

Thanks for reading. I hope you enjoyed it.

--

--

Hitesh Kohli
Hitesh Kohli

Written by Hitesh Kohli

Hi, my name is Hitesh Kohli, I work at Geeks for Geeks as an Android developer. I love messing around with apps and games.

No responses yet