skip to content

Default Arguments

Default parameter values remove most of the reason to write overloads, and the default expression is evaluated on each call. Interviewers follow up with @JvmOverloads, since Java callers cannot see Kotlin defaults without it.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What are default arguments in Kotlin, and how do they let you avoid writing multiple overloads?

level: juniorimportance: must knowfreq 80%

answer

  1. = value in the signature
  2. Replaces telescoping overloads
  3. Mix defaulted and non-defaulted params
  4. Named args skip middle params
  5. One function, many call shapes

basics

~10 s

A default argument gives a parameter a value used when the caller omits it. So one function with defaults replaces many overloaded functions that differ only by which parameters they accept.

solid answer

~40 s

In Kotlin you assign a default in the signature: fun greet(name: String, greeting: String = "Hello"). Callers can pass both arguments or just name, in which case greeting becomes "Hello". This removes the need for telescoping overloads common in Java, where you'd write greet(name) delegating to greet(name, "Hello"). Combined with named arguments, callers can skip middle parameters and set only the ones they care about: greet(name = "Sam"). Any parameter can have a default, the default can be a constant or an expression, and you can mix parameters with and without defaults. Defaults shrink the API surface and keep call sites readable while still allowing full control when needed.

code

kotlin · 8 lines
kotlin
fun connect(host: String, port: Int = 443, tls: Boolean = true): String =
    "$host:$port tls=$tls"

fun main() {
    println(connect("a.com"))                // a.com:443 tls=true
    println(connect("a.com", 80, false))     // a.com:80 tls=false
    println(connect("a.com", tls = false))   // a.com:443 tls=false
}

go deeper

for a junior

Knows the = syntax and that omitting an argument uses the default.

for a middle

Explains the named-argument interaction and mixing defaulted/non-defaulted params.

for a senior

Frames defaults as an API-design tool reducing overload sprawl and discusses call-site clarity.

for a principal

Weighs API evolution, binary compatibility, and when overloads are still warranted (e.g. Java interop).

## What a default argument is A **default argument** is a value attached to a function parameter in its declaration. If a caller does not supply that argument, Kotlin uses the default. This is written with `=` after the parameter type: ```kotlin fun greet(name: String, greeting: String = "Hello"): String = "$greeting, $name!" greet("Sam") // "Hello, Sam!" — greeting defaulted greet("Sam", "Hi") // "Hi, Sam!" greet(name = "Sam") // named argument, greeting defaulted ``` ## Why this replaces overloads In languages without defaults (like Java), you typically write **telescoping overloads** — many functions with the same name differing only in parameter count, each delegating to the fuller one: ```java String greet(String name) { return greet(name, "Hello"); } String greet(String name, String greet) { return greet + ", " + name; } ``` Kotlin collapses all of these into **one** function. Fewer functions means less code to maintain and a smaller API surface. ## Rules you should know - **Any** parameter can have a default, not just the last ones. - You can **mix** parameters with and without defaults. - The default expression can reference earlier parameters (e.g. `fun f(a: Int, b: Int = a)`). - To skip a middle parameter that has a default, use **named arguments**: `f(a = 1, c = 3)`. ## Interaction with named arguments Defaults and **named arguments** are complementary. Named arguments let you specify only the parameters you want by name, letting all others fall back to their defaults — even when the omitted ones are not at the end of the list. ```kotlin fun connect(host: String, port: Int = 443, timeoutMs: Int = 5000, tls: Boolean = true) { /* ... */ } connect("api.example.com", timeoutMs = 1000) // port and tls defaulted ```

  • Can a default expression reference an earlier parameter?
    Yes. Defaults are evaluated left to right, so a later parameter's default can use a value already bound, e.g. fun f(a: Int, b: Int = a * 2).
  • How do you skip a middle parameter that has a default?
    Use named arguments for the ones after it, e.g. f(a = 1, c = 3), letting the middle parameter take its default.

Like a form with pre-filled fields: leave them as-is or overwrite the ones you care about.

saying these in an interview costs you the question

  • Claiming only the last parameter can have a default
  • Saying defaults require named arguments always
  • Confusing default arguments with nullable types
  • Thinking Kotlin still needs telescoping overloads

context

open as a page

When is a default argument expression evaluated — once at definition, or on each call where it is used? Show the consequences.

level: middleimportance: must knowfreq 60%

basics

~10 s

The default expression runs every time the function is called without that argument. It is not computed once and cached, so each defaulted call re-evaluates it freshly.

open as a page

What does @JvmOverloads do, and why is it needed when Kotlin functions with default arguments are called from Java?

level: middleimportance: should knowfreq 55%

basics

~10 s

Java does not understand Kotlin default arguments, so it sees only the full-parameter version. Adding @JvmOverloads tells the compiler to generate extra Java-visible overloads, one per defaulted parameter, so Java callers can omit them.

open as a page

What are the rules for default arguments when overriding a function, and why does Kotlin forbid specifying a new default in the override?

level: seniorimportance: should knowfreq 40%

basics

~10 s

An overriding function must not declare its own default values; it inherits them from the base. This avoids ambiguity about which default applies when you call through a base-type reference.

open as a page

From an API-design and binary-compatibility standpoint, when would you prefer default arguments over explicit overloads, and what are the pitfalls of adding a new defaulted parameter to a published function?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

Defaults give cleaner, smaller APIs and are great for optional configuration. But adding a defaulted parameter to an already-published function changes its bytecode signature, which can break Java callers and previously compiled binaries even though Kotlin source still compiles.

open as a page