Knowledge Map
Kotlin Language
Every keyword from basic syntax to multiplatform and compiler internals — with a plain-English sentence on what each one does in Kotlin.
206
Concepts
23
Groups
134
Must-know
Fundamental
Syntax, types, functions, OOP basics & null safetyval
Declares a read-only variable — you assign it once and can never reassign it, though the object it points to can still change.
var
Declares a mutable variable that can be reassigned any number of times after its initial value is set.
Type Inference
Kotlin figures out a variable's type from the value you assign — you don't need to write it explicitly every time.
String
An immutable sequence of characters — supports triple-quoted raw strings and multiline text out of the box.
String Templates
Embed values directly inside a string using $variable or ${expression} instead of concatenating with +.
Int / Long / Double / Float
Kotlin's numeric primitives — compiled to JVM primitives for performance but treated as objects in the language.
Boolean
A value that is either true or false — used in conditions, when expressions, and logical operators.
Char
A single Unicode character — not the same as a one-character String, though they're easily converted.
Any
The root supertype of every class in Kotlin — equivalent to Java's Object and the top of the type hierarchy.
Unit
The return type of functions that don't return a meaningful value — Kotlin's equivalent of Java's void.
Nothing
A type with no values — used for functions that always throw or loop forever, helping the compiler reason about unreachable code.
Nullable Type (T?)
Adding ? to a type tells Kotlin this value can be null — the compiler forces you to handle null before using it.
Safe Call (?.)
Calls a method or property only if the receiver is non-null, otherwise returns null — no NullPointerException ever.
Elvis Operator (?:)
Provides a fallback value when the left side is null — reads as "use this, or if null, use that instead."
Non-null Assertion (!!)
Forces Kotlin to treat a nullable value as non-null — throws a NullPointerException if it actually is null at runtime.
Smart Cast
After an is-check or null-check, Kotlin automatically treats the variable as the checked type without a manual cast.
let {}
Runs a block only when a nullable value is non-null — the clean alternative to an if-not-null check.
also {}
Like let but passes the object as it rather than the block's result — returns the original object for chaining.
lateinit var
Delays initialisation of a non-null variable — useful for dependency injection fields that are set before first use.
fun
The keyword to declare a function — Kotlin functions are first-class citizens and can be passed as values.
Default Parameters
Assign default values to function parameters so callers can omit them and the default is used automatically.
Named Arguments
Pass arguments by parameter name instead of position — dramatically improves readability for functions with many params.
Single-expression Function
A function whose body is just one expression — use = instead of braces and the return type is inferred automatically.
vararg
Lets a function accept any number of arguments of the same type — they arrive inside the function as an array.
Lambda
An anonymous function literal written as { params -> body } — the foundation of Kotlin's functional style.
Higher-Order Function
A function that accepts other functions as parameters or returns a function — enables patterns like map, filter, and run.
Trailing Lambda
When a lambda is the last parameter, you can move it outside the parentheses — this is why Compose DSLs look clean.
it
The implicit single parameter name inside a lambda — use it when the lambda has exactly one parameter for brevity.
Local Functions
A function declared inside another function — it can access the outer function's variables and helps organise complex logic.
if / else
Works as both a statement and an expression in Kotlin — the result of the chosen branch can be assigned directly.
when
A powerful replacement for switch — can match values, ranges, types, and conditions, and also works as an expression.
for loop
Iterates over any Iterable — use ranges (1..10), collections, or custom objects that implement the iterator protocol.
while / do-while
Standard loops that run a block repeatedly while a condition is true — identical semantics to Java.
Ranges (..)
Creates a sequence of values between two endpoints — 1..10 is inclusive, 1 until 10 excludes the upper bound.
in / !in
Checks if a value belongs to a range or collection — compiles to a simple bounds check for numeric ranges.
break / continue
Skip the rest of a loop iteration (continue) or exit the loop entirely (break) — support labels for nested loops.
Labels (@)
Named markers on loops or lambdas — used with break, continue, or return to target a specific outer scope.
try / catch / finally
Exception handling — try is also an expression so you can assign its result, just like if.
class
Declares a class — properties and functions defined inside it belong to every instance created from it.
Primary Constructor
Parameters declared right after the class name — the concise way to define and initialise properties in one line.
init {}
A block that runs as part of the primary constructor — use it for validation or setup that needs more than an assignment.
data class
Auto-generates equals, hashCode, toString, and copy for you — perfect for plain objects that just hold data.
object
Creates a singleton — a class with exactly one instance that Kotlin creates lazily and you access by its name.
companion object
Lives inside a class and holds members accessed on the class itself rather than instances — Kotlin's static equivalent.
interface
Defines a contract of functions and properties — a class can implement multiple interfaces, unlike class inheritance.
open / override
Classes and functions are final by default — mark them open to allow subclassing, then override to change behaviour.
abstract
Marks a class or function as incomplete — subclasses must provide the implementation before they can be instantiated.
enum class
A type with a fixed set of named values — each constant can hold properties and implement interface functions.
sealed class
A restricted class hierarchy where all subclasses are known at compile time — enables exhaustive when expressions with no else.
List / MutableList
An ordered collection of items — List is read-only, MutableList lets you add, remove, and update elements.
Set / MutableSet
A collection with no duplicate elements — use it when uniqueness matters more than order.
Map / MutableMap
A collection of key-value pairs — look up values by key in constant time and Map guarantees no duplicate keys.
listOf / mutableListOf
Factory functions that create lists — listOf makes a read-only list, mutableListOf an editable one.
map {}
Transforms every element of a collection and returns a new list with the transformed results.
filter {}
Returns a new list containing only the elements that match the given condition.
forEach {}
Iterates over every element in a collection and runs a block — the functional alternative to a for loop.
first / last / find
Retrieves elements by position or condition — first() throws if empty, firstOrNull() returns null safely instead.
groupBy {}
Splits a collection into a Map where elements are grouped by the key returned from the lambda.
sortedBy {}
Returns a new list sorted by the natural order of the value the lambda extracts from each element.
get() / set()
Custom accessors for a property — override them to add validation, transformation, or side effects on read or write.
Backing Field (field)
The actual stored value inside a property's getter or setter — use the field keyword to read or write it without infinite recursion.
lazy {}
Delays initialisation of a property until first access — the lambda runs once, the result is cached for all future reads.
by keyword
Delegates a property's get/set logic to another object — the foundation for lazy, observable, and custom delegates.
Delegated Properties
Lets a reusable helper object handle the storage and logic for a property — write the logic once, apply it anywhere.
observable {}
A built-in delegate that fires a callback every time the property value changes — useful for reactive patterns.
vetoable {}
Like observable but lets you reject the new value in the callback — the property keeps its old value if you return false.
const val
A truly compile-time constant — inlined at every call site and only allowed for primitive types and Strings at top level.
Intermediate
Extension functions, generics, coroutines, scope functions & moreExtension Function
Adds a new function to an existing class without inheriting from it or modifying its source — called like a member function.
Extension Property
Adds a computed property to an existing class — can have a getter but no backing field since you can't add storage.
this inside extension
Refers to the receiver object the extension was called on — the same way this works inside a regular class method.
Receiver Type
The type you're extending — declared before the dot in fun ReceiverType.myExtension() {}.
Nullable Receiver
An extension on a nullable type (fun String?.safeLength()) that can be called even when the receiver is null.
Extension Resolution
Member functions always win over extensions with the same signature — extensions can't override or shadow class members.
Operator Extensions
Adds operator overloads (like + or []) to existing classes via extension — enables clean DSL-style APIs.
let
Calls a lambda with the object as it and returns the lambda result — great for null checks and transforming a value.
run
Calls a lambda with the object as this and returns the lambda result — use for object configuration that returns a value.
apply
Calls a lambda with the object as this and returns the object itself — the go-to for initialising an object's properties.
also
Calls a lambda with the object as it and returns the object itself — perfect for side effects like logging in a chain.
with
A non-extension function that calls a lambda with the object as this — used when you have a non-null object to configure.
takeIf {}
Returns the object if the predicate is true, null if not — the clean way to conditionally continue a chain.
takeUnless {}
Returns the object if the predicate is false, null if true — the inverse of takeIf for negative conditions.
repeat(n) {}
Executes a block n times with the current index — a cleaner alternative to a simple for loop.
Type Parameter <T>
A placeholder for a type that the caller specifies — lets you write one function or class that works for any type.
Upper Bound (<T : Type>)
Constrains T to be a subtype of a specific type — ensures you can call that type's functions on T inside the body.
out (Covariance)
Marks a type parameter as a producer — List<out Animal> accepts a List<Dog> since Dog is an Animal.
in (Contravariance)
Marks a type parameter as a consumer — Comparable<in Dog> can accept a Comparable<Animal>.
reified
Makes a type parameter accessible at runtime inside an inline function — lets you use T::class without reflection tricks.
inline fun
Instructs the compiler to paste the function body at each call site — required for reified and avoids lambda allocation overhead.
Star Projection (*)
A wildcard that says "some unknown type" — use it when the exact type doesn't matter, like List<*>.
where clause
Applies multiple upper bounds to a type parameter when one type constraint isn't enough.
Type Erasure
At runtime, generic type info is gone on the JVM — T becomes Any? and you can't check if something is a List<String>.
suspend fun
A function that can pause its execution without blocking a thread — the building block of all coroutine-based async code.
CoroutineScope
Defines the lifetime of coroutines launched inside it — when the scope is cancelled, all its child coroutines are cancelled too.
launch {}
Starts a new coroutine that runs in the background and returns a Job — use it for fire-and-forget work.
async {}
Starts a coroutine that computes a value and returns a Deferred — call .await() on it to get the result.
await()
Suspends the coroutine until the Deferred result is ready — it does not block the thread while waiting.
Dispatchers.IO
A thread pool optimised for blocking I/O operations — use it for network calls, database reads, and file access.
Dispatchers.Main
Runs on the main (UI) thread — all UI updates must happen here on Android.
Dispatchers.Default
A thread pool for CPU-intensive work — sized to the number of CPU cores, not suitable for blocking I/O.
withContext()
Switches to a different dispatcher for a block and automatically switches back when the block completes.
delay()
Suspends the coroutine for a specified time without blocking the underlying thread — the coroutine-safe alternative to Thread.sleep().
Job
A handle to a running coroutine — lets you check its state, wait for it to finish, or cancel it on demand.
Flow<T>
A cold stream that emits a sequence of values over time — nothing runs until a collector subscribes to it.
flow {}
The builder that creates a Flow — use emit() inside to produce values one at a time.
collect {}
Subscribes to a Flow and runs a block for each emitted value — the terminal operator that triggers execution.
StateFlow
A hot flow that always holds the latest value and replays it to new collectors — the standard for UI state in ViewModels.
SharedFlow
A hot flow for broadcasting events to multiple collectors — configurable replay and buffer for different use cases.
map / filter / transform
Intermediate operators that modify the stream — each returns a new Flow, nothing runs until collect is called.
flowOn()
Changes the dispatcher where the upstream Flow emits its values — use it to push emission to a background thread.
combine()
Merges two or more Flows, emitting a new value whenever any upstream Flow emits using the latest from each.
flatMapLatest {}
Switches to a new Flow for each emission and cancels the previous one — perfect for search-as-you-type.
catch {}
Handles exceptions thrown upstream in a Flow — allows you to emit a fallback value or rethrow gracefully.
Function Type
A type that describes a function's signature — (Int, String) -> Boolean means a function taking Int and String, returning Boolean.
reduce {}
Accumulates a collection into a single value by combining elements left to right with a lambda.
fold {}
Like reduce but you provide an explicit starting value — safer because it works on empty collections too.
flatMap {}
Transforms each element into a collection and then flattens all the results into one flat list.
zip {}
Pairs elements from two collections by index into a list of Pairs — stops at the shorter collection's end.
partition {}
Splits a collection into two lists — the first holds elements matching the predicate, the second holds the rest.
Sequence
A lazy alternative to List operations — evaluates elements one at a time so intermediate collections are never created.
asSequence()
Converts a collection to a Sequence so all chained operations (map, filter) run lazily on each element in turn.
is / !is
Checks if an object is an instance of a type — after the check, the object is smart-cast to that type automatically.
as / as?
as casts unsafely and throws on failure; as? casts safely and returns null instead of throwing if the type doesn't match.
typealias
Creates an alternative name for an existing type — useful for shortening complex function types or improving readability.
Destructuring
Unpacks an object's components into separate variables in one line — works natively with data classes, Pairs, and Maps.
Pair / Triple
Simple generic containers for two or three values — convenient for returning multiple values from a function.
operator fun
Overloads a Kotlin operator (like +, -, [], in) for your custom type by implementing the corresponding named function.
componentN()
The function Kotlin calls during destructuring — data classes generate component1(), component2(), etc. automatically.
invoke()
Overloads the () operator — implement it on a class to let instances be called like functions.
Sequence<T>
A lazily-evaluated collection pipeline; elements are processed one-at-a-time instead of creating intermediate lists at every step.
sequenceOf() / asSequence()
Creates a sequence from existing values or converts a collection to a lazy sequence for chain-operation efficiency.
generateSequence {}
Builds an infinite or finite sequence by repeatedly calling a lambda until it returns null.
sequence {} / yield()
Coroutine-based sequence builder; suspends between yields to produce values on demand without materialising the whole list.
Lazy vs Eager
Sequences avoid intermediate allocations for long pipelines; eager collections are faster for small sets where overhead doesn't accumulate.
Terminal Operations
Operations that trigger evaluation of a sequence: toList(), first(), count(), sum(), fold(), etc.
constrainOnce()
Makes a sequence single-use, throwing an IllegalStateException if iterated more than once — guards against accidental re-consumption.
operator keyword
Marks a function as an overload for a Kotlin operator such as +, -, [], .., or (); the compiler maps the symbol to the named function.
Arithmetic Operators (plus, minus, times, div, rem)
Implement these named functions with the operator modifier to overload +, -, *, /, % for your own types.
Comparison Operators (compareTo)
Implement compareTo to enable <, >, <=, >= on your type; return a negative, zero, or positive Int.
equals & hashCode
Override == behaviour via equals(); must always override hashCode in sync so objects that are equal share the same hash.
rangeTo / in operator
Implement rangeTo to enable .. range creation; implement contains for in / !in membership checks on your type.
Destructuring Declarations
val (a, b) = pair syntax; the compiler calls component1(), component2(), … on the right-hand side to unpack the value.
componentN() functions
Implement component1(), component2(), etc. with the operator modifier (or use data class) to make your type destructurable.
typealias
Gives a new name to an existing type for readability; no new class is created at runtime and no performance overhead is incurred.
Advanced
Coroutine internals, DSLs, reflection, multiplatform & compiler featuresStructured Concurrency
The guarantee that a coroutine's lifetime is bounded by its scope — no coroutine can silently outlive the work that started it.
SupervisorJob
A Job where one child's failure doesn't cancel its siblings — use it in ViewModelScope so one error doesn't kill the scope.
CoroutineExceptionHandler
A context element that catches unhandled exceptions from launch — the coroutine equivalent of a global error handler.
Continuation
The object the compiler uses to represent a paused coroutine — it holds the call stack and local variables at the suspension point.
CPS Transformation
How the compiler converts suspend functions — each suspend call becomes a callback via a Continuation parameter.
Mutex
A coroutine-safe lock — use withLock {} to protect shared mutable state without blocking a thread.
Channel
A communication pipe between coroutines — one sends values, another receives them, like a thread-safe queue.
select {}
Waits on multiple suspending operations simultaneously and runs the block of whichever completes first.
produce {}
Creates a coroutine that sends values into a Channel — a structured way to build producer pipelines.
actor {}
Creates a coroutine that receives messages from a Channel one at a time — serialises access to shared state without locks.
ensureActive()
Throws CancellationException if the coroutine's job is cancelled — use it in tight CPU loops to respect cancellation.
Lambda with Receiver
A lambda that has a specific this — the cornerstone of Kotlin DSLs, letting callers write code as if inside a class.
Function with Receiver
A function type that includes a receiver: (Builder.() -> Unit) — callers can access Builder's members without qualifiers.
@DslMarker
An annotation that prevents accidentally calling outer DSL scopes from inner ones — enforces clean, readable nesting.
Builder Pattern in Kotlin
Using lambda-with-receiver instead of Java's verbose builder class — creates fluent, readable configuration APIs.
apply {} in DSLs
The scope function most commonly used inside DSL builders — configures the receiver and returns it for chaining.
Type-Safe Builders
DSL APIs where the compiler enforces correct nesting and prevents invalid configurations at compile time.
Infix Functions
Single-parameter functions marked infix so they can be called without dots or parentheses — reads like natural language.
Context Receivers
An experimental feature that lets a function declare multiple implicit receivers — enables more powerful DSL composition.
value class
A wrapper class erased to its underlying type at runtime — gives semantic meaning to primitives with zero allocation overhead.
sealed interface
Like a sealed class but allows implementing classes to be in other files — gives sealed hierarchies more flexibility.
data object
A singleton that also gets equals, hashCode, and toString — perfect for singleton sealed hierarchy members like Loading.
Intersection Types
Where a value must satisfy multiple type constraints simultaneously — expressed with where bounds on type parameters.
Nothing?
The only value of this type is null — it's a subtype of every nullable type, which is why null is always a valid default.
Comparable / Comparator
Comparable gives a type a natural ordering; Comparator provides an external, swappable ordering strategy.
Iterable / Iterator
Implement Iterable to make a custom class work in for-loops; Iterator provides the actual hasNext/next protocol.
Sequence vs Flow
Sequences are synchronous and lazy; Flows are asynchronous and suspend — choose based on whether you need coroutines.
Result<T>
A union of success and failure — wraps a value or an exception so you can handle both cases without try-catch.
annotation class
Declares a custom annotation you can attach to classes, functions, or parameters to carry metadata at compile or runtime.
@Retention
Controls how long an annotation survives — SOURCE (compile only), BINARY (in bytecode), or RUNTIME (accessible via reflection).
@Target
Restricts which elements an annotation can be applied to — CLASS, FUNCTION, PROPERTY, VALUE_PARAMETER, etc.
KClass<T>
Kotlin's reflection type for a class — obtained via T::class and gives you the class name, members, and constructors.
KFunction / KProperty
Reflection types for functions and properties — let you call functions or get/set properties dynamically at runtime.
:: (callable reference)
Creates a reference to a function, property, or constructor — pass it as a lambda or use it for reflection.
findAnnotation<T>()
Looks up an annotation of a specific type on a KClass or KFunction — returns null if not present.
@JvmStatic
Makes a companion object function a real static JVM method — required for interop with Java code that expects statics.
@JvmOverloads
Generates Java overloads for each default parameter — lets Java callers omit parameters the same way Kotlin does.
expect / actual
expect declares a platform-agnostic API in common code; actual provides the platform-specific implementation on each target.
commonMain
The source set shared across all platforms — write business logic here once and it compiles for Android, iOS, and Web.
androidMain / iosMain
Platform-specific source sets where you implement actual declarations using native Android or Apple SDKs.
Kotlin/JVM
Compiles Kotlin to JVM bytecode — the target for Android and server-side Kotlin.
Kotlin/Native
Compiles Kotlin to native binaries without a JVM — the target for iOS, macOS, Linux, and Windows.
Kotlin/JS
Compiles Kotlin to JavaScript — enables sharing logic with web front-ends or running Kotlin in Node.js.
Kotlin/Wasm
Compiles Kotlin to WebAssembly — the newest target for high-performance web apps and Compose for Web.
Ktor (KMP)
A multiplatform HTTP client and server framework — the standard choice for networking in shared Kotlin Multiplatform code.
kotlinx.serialization
A multiplatform serialization library that converts Kotlin objects to/from JSON, CBOR, or Protobuf on all targets.
Kotlin Compiler (kotlinc)
The compiler that translates Kotlin source into JVM bytecode, native binaries, or JavaScript depending on the target.
IR Backend
The modern compiler backend that produces an intermediate representation shared across all targets — enables consistent optimisations.
Compiler Plugin
An extension that hooks into the Kotlin compiler — Compose, serialization, and Parcelize are all implemented as compiler plugins.
K2 Compiler
The new Kotlin compiler frontend that is significantly faster to analyse code and produces more precise error messages.
KSP (Kotlin Symbol Processing)
A faster, Kotlin-native alternative to KAPT for annotation processing — reads Kotlin symbols directly without a full compiler round.
KAPT
The older annotation processing bridge that stubs Kotlin to Java so Java annotation processors can run — being replaced by KSP.
Bytecode Inspection
Using the Kotlin bytecode viewer in Android Studio to see exactly what JVM code a Kotlin feature generates.
@OptIn
Opts into using an experimental or unstable API — the author uses @RequiresOptIn to mark the API, you use @OptIn to acknowledge it.
Contracts
A hint to the compiler about a function's behaviour — lets it smart-cast after a custom null-check or assume a lambda runs exactly once.
Platform Types (T!)
Types coming from Java with unknown nullability — Kotlin trusts you on whether they're null, so be careful with them.
@JvmField
Exposes a Kotlin property as a plain JVM field with no getter/setter — required when Java code needs direct field access.
@JvmStatic
Makes a companion object function a real static JVM method so Java code can call it without going through the Companion object.
@Throws
Declares checked exceptions in the JVM signature — required so Java callers know what exceptions to catch from Kotlin functions.
@JvmName
Renames a Kotlin function or property in the compiled JVM bytecode — resolves name clashes when calling from Java.
SAM Conversion
Automatically converts a Kotlin lambda into a Java Single Abstract Method interface — no need to write anonymous classes.
fun interface
A Kotlin SAM interface — declares a functional interface that accepts a lambda anywhere the interface is expected.
@Suppress
Suppresses specific compiler warnings on a declaration — use it sparingly and always with a reason why the warning is safe to ignore.
No concepts found matching your search.