Skip to content
Commitwise
Menu

What is the difference between checked and unchecked exceptions, and how do Kotlin and Swift handle this?

LanguagesMid-level

In shortIn Java, checked exceptions must be caught or declared with throws, and unchecked ones (RuntimeException) don't. Kotlin has only unchecked exceptions. Swift marks functions with throws and every call with try, but errors aren't typed unless you use typed throws.

Model answer

Java splits exceptions in two:

  • Checked (extend Exception): the compiler forces callers to catch them or declare throws. Meant for recoverable situations the caller should plan for, like IOException.
  • Unchecked (extend RuntimeException): no enforcement. Meant for programming errors, like NullPointerException or IllegalArgumentException.

The idea is good, but in practice checked exceptions don’t work with lambdas (stream().map(this::load) can’t throw IOException), they leak implementation details up through layers, and they encourage empty catch blocks. Modern code often wraps them at the edges (UncheckedIOException), always keeping the original as the cause.

Kotlin has no checked exceptions at all. For expected failures, Kotlin code often returns null or a sealed result type instead, and uses @Throws so Java callers can catch exceptions.

Swift takes a middle path: throws in the signature and try at every call site make failure visible, but the error type is any Error unless you use typed throws (throws(ParseError), Swift 6). Swift errors are ordinary return values under the hood, so throwing is cheap.

In all three, cancellation (CancellationError, CancellationException, InterruptedException) travels through the error path and must be propagated, not handled as a failure.

What they're looking for

The Java rule and the reason behind it (recoverable vs programming errors), the practical problems with checked exceptions (lambdas, leaking details), how Kotlin and Swift differ, and good habits like keeping the cause when wrapping.

Common mistakes

  • Claiming Kotlin has checked exceptions, or that Swift errors are exceptions with stack unwinding costs like Java's.
  • Recommending catch (Exception e) {} or wrapping without the cause.
  • Not knowing that lambdas in streams can't throw checked exceptions.

More languages questions

Esc

Type to search the whole site.