Skip to main content
The else clause in Kotlin defines the terminal, fallback execution branch for if and when conditional constructs. It executes exclusively when all preceding boolean conditions or branch matchers evaluate to false or fail to match the evaluation subject. Because Kotlin treats if and when as expressions (constructs that evaluate to a value) rather than strictly as statements, the else clause plays a critical role in compiler-enforced exhaustiveness and type safety.

Mechanics in if Constructs

In an if construct, the else block is bound to the immediately preceding if or else if branch.
  • Statement Context: If the if construct is used as a statement (its return value is ignored), the else clause is optional.
  • Expression Context: If the construct is used as an expression (assigned to a variable, passed as an argument, or returned), the else clause is mandatory. The compiler requires a guaranteed return value for all possible execution paths.

Mechanics in when Constructs

In a when construct, the else clause functions as the default branch, denoted by the else -> syntax. The right-hand side of the -> operator must contain an expression or a block. Strict Ordering Rule: The else -> branch must be the very last branch in the when block. If else -> is placed before any other matchers, the Kotlin compiler throws a strict error ('else' entry must be the last one in a when-expression).
  • Exhaustiveness Requirement: The else branch is mandatory whenever a when construct must be exhaustive, unless the compiler can statically verify that all possible cases are explicitly covered. Exhaustiveness is strictly required in the following scenarios:
    1. Expression Context: Whenever when is used as an expression, regardless of the subject type.
    2. Statement Context: Since Kotlin 1.7.0, non-exhaustive when statements for enum classes, sealed classes/interfaces, and Boolean subjects are enforced as a strict compiler error. If all possible values of these constrained types are not explicitly covered, the else branch is mandatory.

Block Evaluation and Return Types

When an else clause contains a block with multiple statements, the evaluated result of the entire else branch is the value of the last expression within that block. If the branches of an if or when expression return different types, the compiler resolves the overall expression to their closest common supertype.
  • Implicit Unit: If the else branch does not explicitly evaluate to a value, its return type is implicitly Unit. If the corresponding if branch returns a specific type (e.g., Int), the common supertype resolves to Any.
  • The Nothing Edge Case: If the else branch throws an exception or calls a function that returns Nothing (such as TODO()), the compiler resolves the overall expression type strictly to the type of the if branch. Because Nothing is a bottom type (a subtype of all types in Kotlin), it does not force the common supertype to Any.
Tired of Poor Kotlin Skills? Fix That With Deep Grasping!Learn More