Kotlin logoKotlin INTERMEDIATE

Kotlin

Kotlin cheat sheet covering syntax, null safety, coroutines, data classes, extensions, and Android development patterns with examples.

15 min read

Getting Started

Kotlin basics and fundamentals

Variables & Types

Variable declarations and basic types

javascript
💡 Use val by default, var only when mutability is needed
⚡ Type inference makes explicit types often unnecessary
📌 const val for compile-time constants, val for runtime constants
🟢 lateinit for non-null properties initialized after construction

String Templates

String interpolation and manipulation

javascript
💡 Use $ for simple variables, ${} for expressions
⚡ Triple quotes for multiline strings without escaping
📌 trimMargin() removes leading whitespace with | delimiter
🟢 buildString is efficient for complex string construction

Null Safety

Kotlin null safety system

Nullable Types

Working with nullable types safely

javascript
💡 ? makes a type nullable, safe call ?. prevents NPE
⚡ Elvis operator ?: provides default for null values
📌 Avoid !! (not-null assertion) - it defeats null safety
🟢 Smart casts eliminate need for explicit casting after null check

Null Safety Patterns

Advanced null handling patterns

javascript
💡 Scoped functions (let, run, also) handle nullables elegantly
⚡ takeIf/takeUnless return value or null based on predicate
📌 Delegates.notNull() for properties initialized after construction
🟢 Contracts tell compiler about null state after function calls

Functions

Function declarations and features

Function Basics

Function syntax and parameters

javascript
💡 Single expression functions use = instead of braces
⚡ Named arguments improve readability and allow skipping defaults
📌 tailrec optimizes tail recursive functions to loops
🟢 Infix functions allow natural DSL-like syntax

Higher-Order Functions

Functions as parameters and lambdas

javascript
💡 Lambdas are functions defined with { } syntax
⚡ inline functions reduce overhead by inlining at call site
📌 crossinline prevents non-local returns in lambdas
🟢 Function with receiver enables DSL-style APIs

Classes & Objects

Object-oriented programming in Kotlin

Classes

Class declarations and constructors

javascript
💡 Primary constructor is part of class header
⚡ init blocks run during instance initialization
📌 Use field keyword to access backing field in setters
🟢 Class delegation with by keyword promotes composition

Inheritance

Class inheritance and polymorphism

javascript
💡 Classes and members are final by default, use open to allow inheritance
⚡ Sealed classes enable exhaustive when expressions
📌 Interfaces can have default implementations
🟢 Use abstract classes for shared state, interfaces for contracts

Data Classes & Objects

Data classes, objects, and companions

Data Classes

Classes for holding data

javascript
💡 Data classes auto-generate equals(), hashCode(), toString(), copy()
⚡ Destructuring declarations use componentN() functions
📌 Only properties in primary constructor are used in generated methods
🟢 Use copy() to create modified instances immutably

Objects & Companions

Singleton objects and companion objects

javascript
💡 object creates a singleton with thread-safe lazy initialization
⚡ Companion objects are per-class singletons for factory methods
📌 @JvmStatic makes companion methods static in Java
🟢 Object expressions create anonymous classes on the fly

Collections

Lists, Sets, Maps and operations

Collection Types

Lists, Sets, and Maps

javascript
💡 Default collections are immutable, use mutable* for mutability
⚡ to infix function creates Pair for map entries
📌 buildList/buildMap efficiently create immutable collections
🟢 Arrays have fixed size, Lists can be resized (if mutable)

Collection Operations

Transformations and aggregations

javascript
💡 Collection operations return new collections (immutable)
⚡ Use sequences for lazy evaluation of large collections
📌 fold provides initial value, reduce uses first element
🟢 partition splits collection into two based on predicate

Control Flow

Conditionals and loops

Conditionals

if, when, and conditional expressions

javascript
💡 if and when are expressions that return values
⚡ when without argument acts like if-else chain
📌 Sealed classes with when provide exhaustive checks
🟢 Smart casts work in when branches after type checks

Loops

for, while, and loop control

javascript
💡 Ranges (1..5) and progressions (step, downTo) control iteration
⚡ withIndex() provides index-value pairs for iteration
📌 Labels allow breaking/continuing outer loops
🟢 forEach is inline, so return exits the enclosing function

Extensions

Extension functions and properties

Extension Functions

Adding functions to existing types

javascript
💡 Extensions add functions without modifying original class
⚡ Extensions are resolved statically, not polymorphically
📌 Member functions always win over extensions
🟢 Can extend nullable types with null-safe operations

Scope Functions

let, run, with, apply, also

javascript
💡 let/also use it, run/apply/with use this
⚡ let/run/with return result, apply/also return receiver
📌 Use let for null checks and transformations
🟢 Use apply for object configuration, also for side effects

Coroutines

Asynchronous programming with coroutines

Coroutine Basics

Launching and managing coroutines

javascript
💡 suspend functions can call other suspend functions
⚡ async for concurrent execution, await for results
📌 Structured concurrency ensures child coroutines complete
🟢 Use runBlocking only in main or tests

Coroutine Context

Dispatchers and coroutine context

javascript
💡 Dispatchers determine which thread coroutines run on
⚡ Flow is cold (starts on collect), Channel is hot
📌 withContext switches context without creating new coroutine
🟢 StateFlow holds state, SharedFlow broadcasts events

Generics

Generic types and variance

Generic Classes & Functions

Type parameters and constraints

javascript
💡 out for covariance (producers), in for contravariance (consumers)
⚡ reified allows using type parameter in is checks
📌 Star projection (*) represents unknown type argument
🟢 Use where clause for multiple type constraints

Delegation

Class and property delegation

Delegation Patterns

Class delegation and delegated properties

javascript
💡 by keyword enables delegation for classes and properties
⚡ lazy delegates compute value only once on first access
📌 observable and vetoable track/validate property changes
🟢 Map delegation useful for dynamic property storage

DSL Building

Creating domain-specific languages

DSL Construction

Building type-safe DSLs

javascript
💡 Lambda with receiver enables DSL syntax
⚡ @DslMarker prevents scope leaking in nested DSLs
📌 Infix functions create natural language-like APIs
🟢 Type-safe builders provide compile-time validation

Annotations & Reflection

Custom annotations and reflection

Annotations

Creating and using annotations

javascript
💡 @Target specifies where annotation can be used
⚡ @Retention determines if annotation is available at runtime
📌 Reflection requires kotlin-reflect dependency
🟢 Use @Jvm* annotations for Java interoperability

Interoperability

Java interop and platform types

Java Interop

Calling Java from Kotlin and vice versa

javascript
💡 Platform types (!) can be null, handle carefully
⚡ @JvmStatic makes companion members static in Java
📌 SAM conversion works for Java functional interfaces
🟢 Use @JvmOverloads for Java-friendly default parameters

Advanced Features

Inline classes, contracts, and more

Inline & Value Classes

Performance optimizations

javascript
💡 inline eliminates function call overhead
⚡ Value classes wrap primitives without runtime overhead
📌 Contracts tell compiler about function behavior
🟢 Type aliases improve code readability