skip to content

Which runtime exception types does the Kotlin stdlib throw for common operations, and when is each raised?

level: middleimportance: must knowfreq 64%

answer

  1. toInt -> NumberFormatException
  2. !! / platform null -> NullPointerException
  3. bad index -> IndexOutOfBoundsException
  4. empty first()/max() -> NoSuchElementException
  5. bad as -> ClassCastException; mutate-while-iterate -> ConcurrentModificationException

basics

~20 s

The stdlib throws specific runtime exceptions: bad numeric text gives NumberFormatException, a null in a non-null spot gives NullPointerException, a bad index gives IndexOutOfBoundsException, an empty collection's first() gives NoSuchElementException, and a wrong cast gives ClassCastException.

solid answer

~30 s

Common stdlib-thrown types (all unchecked `RuntimeException`s): `"x".toInt()` on non-numeric input throws `NumberFormatException` (a subtype of `IllegalArgumentException`). A non-null-asserting `!!` on null, or an unexpected platform null, throws `NullPointerException` (specifically `KotlinNullPointerException` for `!!`). Indexing a list out of range throws `IndexOutOfBoundsException`; on strings/arrays the JVM may surface `ArrayIndexOutOfBoundsException`/`StringIndexOutOfBoundsException`. `list.first()` / `single()` / `max()` on an empty collection throws `NoSuchElementException`. An invalid `as` cast throws `ClassCastException`. Mutating a collection while iterating throws `ConcurrentModificationException`. The precondition helpers throw `IllegalArgumentException` (`require`) and `IllegalStateException` (`check`/`error`). Knowing the exact type lets you catch narrowly, e.g. `catch (e: NumberFormatException)` rather than a blanket `Exception`.

code

kotlin · 7 lines
kotlin
fun demo() {
    "x".toInt()                 // NumberFormatException
    (null as String?)!!         // NullPointerException
    listOf(1)[3]                // IndexOutOfBoundsException
    emptyList<Int>().first()    // NoSuchElementException
    ("s" as Any) as Int         // ClassCastException
}

go deeper

for a junior

Names a few common ones (NumberFormatException, NullPointerException, IndexOutOfBoundsException).

for a middle

Maps each operation to its exact exception and knows the OrNull alternatives.

for a senior

Explains the subtype relationships and why narrow catches matter; mentions platform-type NPEs.

for a principal

Defines codebase conventions for safe (OrNull/as?) vs throwing variants and exception-handling boundaries.

## stdlib runtime exception types All are **unchecked** `RuntimeException` subtypes. Catch the **most specific** one you can. ### NumberFormatException Thrown by string-to-number parsing when the text isn't a valid number. ```kotlin "12a".toInt() // NumberFormatException "".toLong() // NumberFormatException ``` It extends `IllegalArgumentException`. The safe-parse variants (`toIntOrNull()`) return `null` instead of throwing. ### NullPointerException (NPE) - `value!!` on a null receiver throws `KotlinNullPointerException` (an NPE). - A Java method declared returning a non-null but returning null (a *platform type*) can surface an NPE at the use site. ```kotlin val x: String? = null x!!.length // NullPointerException ``` ### IndexOutOfBoundsException Accessing an index outside a collection/array/string range. ```kotlin listOf(1, 2)[5] // IndexOutOfBoundsException ``` JVM arrays/strings may throw the narrower `ArrayIndexOutOfBoundsException` / `StringIndexOutOfBoundsException`, both subclasses. ### NoSuchElementException From terminal accessors on an **empty** source, or an exhausted iterator. ```kotlin emptyList<Int>().first() // NoSuchElementException emptyList<Int>().max() // NoSuchElementException ``` The `...OrNull()` variants (`firstOrNull`, `maxOrNull`) avoid it. ### ClassCastException An unchecked `as` cast to an incompatible type. ```kotlin val a: Any = "s" a as Int // ClassCastException ``` The safe cast `as?` yields `null` instead. ### ConcurrentModificationException Structurally modifying a collection during iteration. ```kotlin val m = mutableListOf(1, 2, 3) for (e in m) { if (e == 2) m.remove(e) } // ConcurrentModificationException ``` Use `iterator.remove()` or `removeAll { ... }` instead. ### Precondition exceptions - `require(cond)` -> `IllegalArgumentException` (bad argument). - `check(cond)` / `error(msg)` -> `IllegalStateException` (bad object/state). ## Picking the right type Narrow catches improve clarity and avoid masking unrelated bugs: ```kotlin val n = try { raw.toInt() } catch (e: NumberFormatException) { 0 } ``` Catching `Exception` here would also swallow programming errors. ## Key terms - **Platform type**: a Java-originated type with unknown nullability; can cause NPEs. - **OrNull variants**: non-throwing stdlib counterparts. - **Terminal accessor**: `first`, `single`, `max`, etc., that demand at least one element.

  • How do you avoid NumberFormatException and NoSuchElementException without try/catch?
    Use the OrNull variants: toIntOrNull() and firstOrNull()/maxOrNull(), which return null instead of throwing.
  • What does a safe cast 'as?' do on a type mismatch?
    It returns null instead of throwing ClassCastException.

saying these in an interview costs you the question

  • Thinking toInt() returns null on bad input (it throws)
  • Catching broad Exception when a specific type exists
  • Not knowing first() on an empty list throws NoSuchElementException
  • Believing !! is safe
  • Confusing as (throws) with as? (returns null)

context