Sebagian besar kode yang kita tulis jatuh pada dua kategori: statement (perintah yang dijalankan tanpa menghasilkan nilai) dan expression (kode yang menghasilkan nilai). Pada chapter ini kita akan membedah perbedaan keduanya, melihat bagaimana Kotlin mengubah if, when, dan try menjadi expression, dan membandingkan dengan Java yang memperlakukan ketiganya sebagai statement. Pemahaman ini membuat kode Kotlin jauh lebih ringkas.

Definisi: Statement vs Expression #

Expression adalah konstruksi bahasa yang menghasilkan nilai. Contoh paling sederhana adalah literal 42, operasi aritmetika 1 + 2, atau pemanggilan function hitungTotal(5000, 3).

Statement adalah konstruksi yang melakukan aksi tetapi tidak menghasilkan nilai. Contoh: deklarasi variabel val x = 5, perulangan for, atau pemanggilan println(...).

Pada banyak bahasa turunan C (termasuk Java), if, switch, dan try adalah statement — mereka menjalankan cabang kode tetapi tidak menghasilkan nilai yang bisa ditugaskan ke variabel. Kotlin berbeda: ketiganya adalah expression yang mengembalikan nilai.

if sebagai Expression #

Pada Kotlin, if dapat berdiri sendiri sebagai statement (untuk efek samping) atau dipakai sebagai expression yang menghasilkan nilai:

kotlin if sebagai expression
val suhu = 32
val status = if (suhu >= 30) "panas" else "sejuk"
// status == "panas"

Padanannya dalam Java memerlukan statement if-else eksplisit yang menugaskan ke variabel di tiap cabang:

java Java: if adalah statement, bukan expression
String status;
if (suhu >= 30) {
    status = "panas";
} else {
    status = "sejuk";
}

Versi Kotlin lebih ringkas: satu baris ekspresi menggantikan lima baris Java. Kompilator menyimpulkan tipe hasil if dari tipe kedua cabang; bila kedua cabang memiliki tipe berbeda, hasilnya adalah supertype umum (misal Any).

Contoh Lengkap dengan if, when, dan try #

Berikut program yang memadukan ketiganya sebagai expression:

kotlin
fun main() {
    // if sebagai expression
    val suhu = 32
    val status = if (suhu >= 30) "panas" else "sejuk"
    println("Cuaca: $status")

    // when sebagai expression dengan banyak cabang
    val kode = 404
    val pesan = when (kode) {
        200 -> "Sukses"
        in 300..399 -> "Pengalihan"
        404 -> "Tidak ditemukan"
        in 500..599 -> "Kesalahan server"
        else -> "Tidak diketahui"
    }
    println("Kode $kode -> $pesan")

    // try sebagai expression
    val angka = amanParse("42")
    println("Hasil parse: $angka")

    // if bersarang sebagai expression
    val nilai = 78
    val predikat = if (nilai >= 90) {
        "A"
    } else if (nilai >= 80) {
        "B"
    } else if (nilai >= 70) {
        "C"
    } else {
        "D"
    }
    println("Nilai $nilai -> predikat $predikat")
}

fun amanParse(input: String): Int {
    return try {
        input.toInt()
    } catch (e: NumberFormatException) {
        0
    }
}

Output yang Dihasilkan:

text
Cuaca: panas
Kode 404 -> Tidak ditemukan
Hasil parse: 42
Nilai 78 -> predikat C

Mari kita bedah bagian kunci:

  1. Baris 4 (val status = if (suhu >= 30) "panas" else "sejuk") — kedua cabang menghasilkan String, sehingga status bertipe String.
  2. Baris 9-15 (val pesan = when (kode) { ... }) — when menggantikan switch Java; setiap cabang adalah expression. Cabang in 300..399 memakai range check, dan else wajib bila kompilator tidak dapat membuktikan kelelahan cabang.
  3. Baris 18 (val angka = amanParse("42")) — function amanParse memakai try sebagai expression; blok try mengembalikan hasil input.toInt(), dan blok catch mengembalikan 0 sebagai fallback.
  4. Baris 21-31 (val predikat = if (...) { ... } else if ...) — if-else if-else bertingkat tetap valid sebagai expression; setiap cabang menulis string sebagai nilai terakhirnya.

Aturan Tipe pada Expression if dan when #

Saat if atau when dipakai sebagai expression, kompilator menerapkan aturan tipe berikut:

  • Semua cabang harus menghasilkan tipe yang kompatibel.
  • Bila satu cabang bertipe String dan cabang lain Int, hasil menjadi Any (supertype umum).
  • Bila salah satu cabang tidak mengembalikan nilai (hanya return atau melempar exception), cabang tersebut tidak dihitung dalam inferensi tipe.
  • Cabang Nothing (misal melempar exception) tidak memengaruhi inferensi tipe cabang lain.
kotlin Cabang dengan tipe berbeda
val hasil: Any = if (kondisi) "teks" else 42   // Any sebagai supertype
val tetap: String = if (kondisi) "ok" else fail("gagal")  // fail() -> Nothing

try sebagai Expression #

Pada Java, blok try-catch adalah statement; di Kotlin, try adalah expression yang mengembalikan nilai dari baris terakhirnya:

kotlin try expression mengembalikan nilai
fun amanParse(input: String): Int {
    return try {
        input.toInt()
    } catch (e: NumberFormatException) {
        0
    }
}

Function amanParse di atas mengembalikan Int dari blok try saat parsing berhasil, atau Int 0 dari blok catch saat gagal. Tanpa fitur ini, kita perlu variabel sementara di luar try, yang menambah boilerplate.

when Lebih Kuat dari switch #

when adalah pengganti switch Java yang jauh lebih ekspresif. Selain konstanta, when mendukung pola berikut:

PolaContoh
Konstanta200 -> "Sukses"
Rangein 300..399 -> "Pengalihan"
Tipeis String -> "teks"
Ekspresi bebaskode % 2 == 0 -> "genap"
Multi-nilai200, 201, 202 -> "Sukses"

Berbeda dengan switch Java yang memerlukan break di tiap case, when otomatis berhenti pada cabang yang cocok — tidak ada fall-through.

Perbandingan dengan Java #

Tabel berikut merangkum perbedaan treatment if, switch/when, dan try antara Kotlin dan Java:

KonstruksiKotlinJava
ifExpression dan statementHanya statement
when / switchExpression; tanpa fall-throughStatement; fall-through dengan break
tryExpression; mengembalikan nilaiStatement; butuh variabel luar
forHanya statementHanya statement
while / do-whileHanya statementHanya statement

Referensi Lanjutan #

Memperlakukan if, when, dan try sebagai expression mengurangi boilerplate dan membuat kode deklaratif. Dengan pola ini, kita siap melihat bagaimana kita menamai setiap simbol yang kita buat — yaitu aturan identifier dan keyword Kotlin — pada chapter Identifier dan Keywords.