Bahasa Kotlin terus berkembang. Sejak versi 1.9, JetBrains memperkenalkan sejumlah fitur baru yang menyederhanakan pola umum dan mengurangi boilerplate. Versi 2.0 menandai pergantian kompilator lama (K1) ke arsitektur K2 yang lebih cepat. Versi 2.1 menstabilkan when guard conditions, dan 2.2 mengganti context receiver dengan context parameter yang lebih ekspresif. Pada chapter ini kita akan memetakan fitur-fitur utama, melihat kapan masing-masing diperkenalkan, dan mencoba contoh ringkas untuk masing-masing fitur agar kita tahu kapan harus memakainya di kode produksi.

Peta Fitur per Versi #

Tabel berikut merangkum fitur modern Kotlin dan kapan fitur tersebut stabil. Kita bisa memakai tabel ini untuk memutuskan language version minimum saat menulis Gradle build:

VersiFitur stabilCatatan
1.9data object (beta), KMP stabilSebagian besar stabil di 2.0
2.0K2 compiler default, data object stabilPeningkatan kecepatan kompilasi
2.1when guard conditions (is T && cond)Sintaks guard di branch when
2.2Context parameters (context(value: T))Pengganti context receiver

Demonstrasi Ringkas #

Cuplikan berikut merangkum empat fitur utama (kecuali context parameter yang butuh Kotlin 2.2+) dalam satu file runnable:

kotlin
// modern_kotlin_language_features.kt
// Ringkasan fitur modern Kotlin (1.9 - 2.0):
// - data object
// - when guard (kotlin 2.1+ — disimulasikan manual)
// - builder inference (buildList)
// - definitely non-nullable (T & Any)
// - K2 compiler (2.0+)

// 1. data object — singleton dengan toString/equals/hashCode otomatis
data object Konfigurasi {
    val versi = "2.0.21"
    val namaRuntime = "JVM"
}

// 2. Builder inference — buildList/buildMap menyimpulkan tipe dari lambda
fun buatDaftarSiswa(): List<String> = buildList {
    add("Budi")
    add("Siti")
    add("Dewi")
}

fun buatPetaSkor(): Map<String, Int> = buildMap {
    put("Budi", 85)
    put("Siti", 90)
    put("Dewi", 78)
}

// 3. T & Any — paksa tipe parameter non-nullable
fun <T> cetakHashCodeAman(x: T & Any): Int = x.hashCode()

// 4. when dengan in-range dan multiple values
fun kategoriSkor(skor: Int): String = when (skor) {
    in 90..100 -> "A"
    in 80..89 -> "B"
    in 70..79 -> "C"
    in 60..69 -> "D"
    else -> "E"
}

// 5. Range hingga data object sebagai sealed child
sealed interface Aksi {
    data object Mulai : Aksi
    data object Hentikan : Aksi
    data class Custom(val nama: String) : Aksi
}

fun ringkasAksi(a: Aksi): String = when (a) {
    Aksi.Mulai -> "Memulai proses"
    Aksi.Hentikan -> "Menghentikan proses"
    is Aksi.Custom -> "Aksi kustom: ${a.nama}"
}

fun main() {
    println("=== Modern Kotlin Language Features ===")
    println("Ringkasan fitur baru Kotlin 1.9 - 2.0")
    println()

    println("--- 1. data object ---")
    println("Konfigurasi: $Konfigurasi")
    println("toString otomatis tanpa override manual")

    println()
    println("--- 2. Builder inference (buildList, buildMap) ---")
    val siswa = buatDaftarSiswa()
    println("Daftar siswa: $siswa")
    val skor = buatPetaSkor()
    println("Peta skor:")
    skor.forEach { (k, v) -> println("  $k -> $v") }

    println()
    println("--- 3. Definitely non-nullable types (T & Any) ---")
    val hash = cetakHashCodeAman("halo")
    println("hashCode(\"halo\") = $hash")
    println("T & Any memaksa tipe parameter non-nullable di scope tertentu")

    println()
    println("--- 4. when dengan range ---")
    listOf(95, 82, 73, 65, 40).forEach {
        println("  skor $it -> ${kategoriSkor(it)}")
    }

    println()
    println("--- 5. data object sebagai sealed child ---")
    val aksiList: List<Aksi> = listOf(
        Aksi.Mulai,
        Aksi.Custom("backup"),
        Aksi.Hentikan
    )
    aksiList.forEach { println("  ${ringkasAksi(it)}") }

    println()
    println("--- 6. K2 compiler (Kotlin 2.0+) ---")
    println("K2 compiler: arsitektur frontend baru, lebih cepat,")
    println("inferensi tipe lebih akurat, diperkenalkan di Kotlin 2.0.")

    println()
    println("--- 7. Ringkasan versi dan fitur ---")
    val fitur = listOf(
        "1.9 - data object (beta), KMP stabil",
        "2.0 - K2 compiler default, data object stabil",
        "2.1 - when guard conditions stabil",
        "2.2 - context parameters (pengganti context receivers)"
    )
    fitur.forEach { println("  - $it") }
}

Output yang Dihasilkan:

text
=== Modern Kotlin Language Features ===
Ringkasan fitur baru Kotlin 1.9 - 2.0

--- 1. data object ---
Konfigurasi: Konfigurasi
toString otomatis tanpa override manual

--- 2. Builder inference (buildList, buildMap) ---
Daftar siswa: [Budi, Siti, Dewi]
Peta skor:
  Budi -> 85
  Siti -> 90
  Dewi -> 78

--- 3. Definitely non-nullable types (T & Any) ---
hashCode("halo") = 3194940
T & Any memaksa tipe parameter non-nullable di scope tertentu

--- 4. when dengan range ---
  skor 95 -> A
  skor 82 -> B
  skor 73 -> C
  skor 65 -> D
  skor 40 -> E

--- 5. data object sebagai sealed child ---
  Memulai proses
  Aksi kustom: backup
  Menghentikan proses

--- 6. K2 compiler (Kotlin 2.0+) ---
K2 compiler: arsitektur frontend baru, lebih cepat,
inferensi tipe lebih akurat, diperkenalkan di Kotlin 2.0.

--- 7. Ringkasan versi dan fitur ---
  - 1.9 - data object (beta), KMP stabil
  - 2.0 - K2 compiler default, data object stabil
  - 2.1 - when guard conditions stabil
  - 2.2 - context parameters (pengganti context receivers)

Pada cuplikan di atas, data object Konfigurasi menghasilkan toString otomatis tanpa override manual; buildList { add(...) } memanfaatkan builder inference sehingga tipe elemen disimpulkan dari isi lambda; T & Any memaksa tipe parameter non-nullable di scope method; dan when (skor) { in 90..100 -> ... } memakai range check yang lebih ringkas daripada if-else berantai.

Daftar Fitur dan Tujuannya #

Kita akan membahas tuntas masing-masing fitur pada chapter tersendiri di section ini:

  • data object — singleton dengan toString/equals/hashCode otomatis. Cocok untuk deklarasi konstanta terstruktur dan sealed child tanpa state.
  • when guard conditions — when (x) { is String && x.length > 5 -> ... }. Menggabungkan smart cast dan kondisi boolean di satu branch.
  • when expressions lanjutan — exhaustive when untuk sealed class, binding variabel subject (when (val x = ...) { ... }), destructuring, dan multiple values.
  • T & Any (definitely non-nullable) — memaksa tipe parameter generik T menjadi non-nullable di scope tertentu, misalnya untuk memanggil hashCode() tanpa risiko NPE.
  • Builder inference — kompilator menyimpulkan tipe parameter generik dari isi lambda buildList { } / buildMap { } tanpa anotasi eksplisit.
  • K2 compiler — arsitektur frontend baru yang lebih cepat dan akurat dalam inferensi tipe. Default di Kotlin 2.0+.
  • Context parameters — fitur Kotlin 2.2+ yang menggantikan context receiver; menerima receiver implisit dengan deklarasi eksplisit (context(logger: Logger)).

Cara Mengaktifkan Fitur Eksperimental #

Beberapa fitur berstatus eksperimental sebelum stabil. Kita bisa mengaktifkannya lewat flag compiler:

text Aktivasi fitur eksperimental di Gradle
kotlin {
    compilerOptions {
        languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.VERSION_2_0)
        apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.VERSION_2_0)
        // Untuk fitur eksperimental:
        // freeCompilerArgs.add("-XXLanguage:+WhenGuards")
    }
}

Untuk fitur yang sudah stabil di versi target, kita tidak perlu menambahkan flag apa pun — kompilator mendeteksinya otomatis dari languageVersion. Saat menulis kode produksi, hindari memakai flag eksperimental kecuali kita siap menanggung perubahan sintaks pada versi berikutnya.

Referensi Lanjutan #

Selanjutnya #

Setelah memetakan fitur modern, langkah berikutnya adalah membedah fitur yang paling ditunggu — context parameters — yang menggantikan context receiver lama dan memberi cara baru untuk menyuntik dependensi implisit tanpa boilerplate parameter.