Kotlin Cheatsheet
Interop & Tooling
Use this Kotlin reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Calling Java from Kotlin
Java code just works — Kotlin compiles to regular JVM bytecode.
import java.time.LocalDate import java.util.PriorityQueue val today = LocalDate.now() val pq = PriorityQueue<Int>()
| Java | Seen from Kotlin |
|---|---|
getName() / setName(v) | property name |
isActive() | property isActive |
void | Unit |
un-annotated String | platform type String! (unknown nullability) |
@Nullable String | String? |
int[] | IntArray |
| static members | ClassName.member |
Platform types are the interop trap: the compiler can't verify nullability, so annotate explicitly at the boundary (val s: String? = javaApi.value()) instead of letting NPEs surface deep in Kotlin code.
Java identifiers that collide with Kotlin keywords are escaped with backticks:
val stdin = System.`in` Mockito.`when`(repo.load()).thenReturn(user)
Calling Kotlin from Java
Top-level functions in Utils.kt land on a class UtilsKt; rename with a file annotation:
@file:JvmName("StringUtils") package demo fun capitalizeWords(s: String) = s.split(" ").joinToString(" ") { w -> w.replaceFirstChar { it.uppercase() } } // Java: StringUtils.capitalizeWords("hello world")
| Annotation | Effect for Java callers |
|---|---|
@JvmStatic | companion/object member becomes a real static method |
@JvmField | expose a property as a public field (no getter) |
@JvmOverloads | generate overloads for each default parameter |
@JvmName("x") | rename a function/getter in bytecode |
@Throws(IOException::class) | declare checked exceptions in the signature |
@JvmRecord | compile a data class to a Java record |
class Temperature(val celsius: Double) { companion object { @JvmStatic fun fromFahrenheit(f: Double) = Temperature((f - 32) / 1.8) } } @JvmOverloads fun connect(host: String, port: Int = 5432, tls: Boolean = true) { } // Java sees connect(host), connect(host, port), connect(host, port, tls)
SAM conversion & fun interfaces
Lambdas convert automatically to Java single-abstract-method interfaces:
val t = Thread { println("run") } // Runnable executor.submit { compute() } // Callable list.removeIf { it < 0 } // Predicate // Kotlin-side SAM types must be declared `fun interface`: fun interface Transformer { fun transform(s: String): String } val upper = Transformer { it.uppercase() }
Compiler & CLI
kotlinc Main.kt -include-runtime -d app.jar # standalone jar java -jar app.jar kotlinc -version # 2.x = K2 compiler line kotlin Main.kt # compile + run a script-style file
Kotlin 2.0+ ships the K2 compiler by default (faster builds, smarter smart casts). Multiplatform note: kotlin("jvm") targets the JVM only; KMP projects use kotlin("multiplatform") with jvm(), js(), and native targets sharing commonMain code.
Tooling quick facts
| Tool | Note |
|---|---|
| ktlint / ktfmt | formatting + lint (official style is 4-space indent) |
| detekt | static analysis, complexity/code-smell rules |
| Dokka | KDoc → HTML/Javadoc documentation |
| kotlinx.serialization | @Serializable + compiler plugin; Json.encodeToString(obj) |
| KSP | annotation processing (successor to kapt) |
// kotlinx.serialization in one glance @Serializable data class Event(val id: Int, val tags: List<String> = emptyList()) val json = Json.encodeToString(Event(1, listOf("a"))) val back = Json.decodeFromString<Event>(json)