# Type Checks, Casts and the Type Hierarchy — Kotlin

Source: https://www.skillbyai.com/en/kotlin/n-casts

> is, as, as? and Any, Unit, Nothing.

## Checking and converting types

`x is Type` checks a type and smart casts `x` in the guarded scope; `!is` is the negation. `x as Type` is an **unsafe cast** that throws `ClassCastException` on failure, while `x as? Type` is a **safe cast** returning `null`. At the top of the hierarchy is `Any` (and `Any?` for nullable values). Functions with no useful return value return `Unit`. `Nothing` is the type of expressions that never complete normally, such as `throw` or `TODO()`, which is why `?: throw ...` type-checks. Numbers do not convert implicitly: use `toLong()`, `toDouble()` and similar.

## Safe casts and explicit conversion

No implicit widening.

```kotlin
fun lengthOf(value: Any): Int {
    if (value is String) return value.length          // smart cast
    val list = value as? List<*> ?: return -1          // safe cast + elvis
    return list.size
}

fun fail(message: String): Nothing = throw IllegalStateException(message)

fun main() {
    val small: Int = 42
    val big: Long = small.toLong()       // explicit conversion required
    val ratio = small / 5.0              // Int / Double gives Double
    val config: String = System.getenv("APP_MODE") ?: fail("APP_MODE not set")
}
```

## Prefer is over as

An `is` check followed by a smart cast is safer and clearer than an unchecked `as`. Reach for `as?` when a failed cast is a normal outcome.

**Quiz:** What does `value as? String` return if `value` is an Int?

- [ ] An empty string
- [ ] It throws ClassCastException
- [ ] The Int converted to text
- [x] null

*Answer:* null. as? is the safe cast.
