# Nullable Types and Safe Operators — Kotlin

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

> String versus String?, ?., ?: and !!.

## Null is part of the type

In Kotlin a `String` can never hold `null`; a `String?` can. The compiler refuses to call members on a nullable value directly. The **safe call** `a?.length` returns `null` if `a` is null. The **elvis operator** `a ?: default` supplies a fallback (it can also `return` or `throw`). The **not-null assertion** `a!!` converts to non-null and throws a `NullPointerException` if the value is null, so use it rarely. After `if (a != null)`, the compiler **smart casts** `a` to the non-null type inside the branch, as long as it is a local `val` or a value it can prove does not change.

## Nulls become compile-time errors

Kotlin separates nullable and non-null types and narrows types automatically after checks.

![Three ideas: nullable types and safe operators, when and ranges, type checks and casts.](assets/figures/kotlin/section-2-map.svg) — Figure 2.1 — Nullable value, safe call, elvis default, non-null result.

## Handling a missing value

Safe call, elvis and smart cast.

```kotlin
data class User(val name: String, val email: String?)

fun emailDomain(user: User): String {
    val email = user.email ?: return "no email"     // elvis with early return
    return email.substringAfter("@")               // email is String here
}

fun nameLength(name: String?): Int {
    if (name != null) {
        return name.length            // smart cast to String
    }
    return 0
}

fun shout(text: String?): String? = text?.uppercase()   // null stays null
```

## Treat !! as a code smell

Each `!!` is a place where you told the compiler "trust me". Prefer `?:` with a sensible default, an early return, or `requireNotNull(x) { "message" }` which throws with a clear message.

**Quiz:** What does `user?.email ?: "none"` evaluate to when `user` is null?

- [ ] null
- [x] "none"
- [ ] It throws NullPointerException
- [ ] An empty string

*Answer:* "none". The safe call yields null and elvis supplies the fallback.
