Compiler Kotlin tidak hanya melaporkan error saat kompilasi gagal, tetapi juga warning saat kode sah secara sintaks tetapi berpotensi bermasalah. Warning adalah tembok pertahan pertama sebelum bug masuk ke produksi. Sayangnya banyak developer mengabaikan warning atau langsung memakai @Suppress tanpa pertimbangan. Pada chapter ini kita akan membedah warning umum di Kotlin, kapan memperbaikinya, dan kapan @Suppress memang merupakan jawaban yang tepat.

Warning Umum di Kotlin #

Beberapa warning yang sering muncul:

WarningPenyebabTindakan
UNUSED_VARIABLEVariabel dideklarasikan tetapi tidak dipakaiHapus atau pakai
UNUSED_PARAMETERParameter method tidak dipakaiHapus atau pakai
UNUSED_EXPRESSIONEkspresi tidak menimbulkan efek sampingHapus atau periksa logic
DEPRECATIONAPI sudah ditandai @DeprecatedMigrasi ke API baru
PARAMETER_NAME_SHADOWINGParameter memiliki nama yang sama dengan field/parameter outerRename parameter
UNCHECKED_CASTCast as tanpa pengecekan runtimePakai as? + elvis
REDUNDANT_MODIFIERModifier tidak diperlukanHapus modifier
UNUSED_RECEIVER_PARAMETERExtension receiver tidak dipakai dalam bodyPertimbangkan jadi top-level function

Demo Compiler Warnings #

Berikut kode yang sengaja memunculkan berbagai warning. Kode ini dikompilasi dengan @Suppress pada level yang sesuai.

kotlin
// Demo compiler warnings: bagaimana compiler memberi peringatan dan cara menanganinya.

// === 1. @Suppress untuk memilih tidak menampilkan warning tertentu ===
@Suppress("UNUSED_VARIABLE", "UNUSED_PARAMETER", "UNUSED_EXPRESSION")
fun demonstrasiUnused(): Int {
    val variabelTakTerpakai = 42
    val hasil = 10 + 5
    100  // expression tak terpakai
    return hasil
}

// === 2. Parameter shadowing ===
class Akun(val nama: String) {
    // Parameter `nama` pada constructor dan parameter `nama` di method saling membingungkan
    fun ubahNama(nama: String) {
        // Warning: Parameter 'nama' shadows member property 'nama' (di IntelliJ)
        println("Sebelum: ${this.nama}, akan ubah ke: $nama (tidak benar-benar mengubah property)")
    }
}

// === 3. @Deprecated API ===
@Deprecated("Gunakan hitungTotalV2; v1 akan dihapus di versi 2.0", ReplaceWith("hitungTotalV2(items)"))
fun hitungTotalV1(items: List<Int>): Int {
    var total = 0
    for (x in items) total += x
    return total
}

fun hitungTotalV2(items: List<Int>): Int = items.sum()

// === 4. Cast yang tidak aman (unchecked cast) ===
@Suppress("UNCHECKED_CAST")
fun bacaListSebagaiInt(map: Map<String, Any>, key: String): List<Int> {
    return map[key] as List<Int>
}

// === 5. Var property yang bisa diganti dengan val ===
class Konfigurasi(var host: String) {
    // IntelliJ: "Var property bisa menjadi val"
    fun ringkas(): String = host
}

fun main() {
    println("=== Demo Compiler Warnings ===")

    // 1. Unused variable
    val hasil = demonstrasiUnused()
    println("Hasil demonstrasiUnused: $hasil")

    // 2. Shadowing
    val akun = Akun("Budi")
    akun.ubahNama("Siti")

    // 3. Deprecated
    val total = hitungTotalV1(listOf(10, 20, 30))
    println("Total V1 (deprecated): $total")

    val total2 = hitungTotalV2(listOf(10, 20, 30))
    println("Total V2 (current): $total2")

    // 4. Unchecked cast
    val data: Map<String, Any> = mapOf("angka" to listOf(1, 2, 3))
    val daftar = bacaListSebagaiInt(data, "angka")
    println("Daftar dari map: $daftar")

    // 5. Var -> val
    val cfg = Konfigurasi("localhost")
    println("Host: ${cfg.host}, ringkas: ${cfg.ringkas()}")

    // 6. Tailrec warning untuk fungsi rekursif non-tail
    println()
    println("=== Tips menangani warning ===")
    println("1. Unused -> hapus atau pakai")
    println("2. Deprecated -> migrasi ke API baru")
    println("3. Shadowing -> rename parameter atau gunakan `this.nama`")
    println("4. Cast tidak aman -> gunakan `as?` + elvis")
    println("5. @Suppress hanya untuk kasus yang sudah dipertimbangkan")
}

Output yang Dihasilkan:

text
=== Demo Compiler Warnings ===
Hasil demonstrasiUnused: 15
Sebelum: Budi, akan ubah ke: Siti (tidak benar-benar mengubah property)
Total V1 (deprecated): 60
Total V2 (current): 60
Daftar dari map: [1, 2, 3]
Host: localhost, ringkas: localhost

=== Tips menangani warning ===
1. Unused -> hapus atau pakai
2. Deprecated -> migrasi ke API baru
3. Shadowing -> rename parameter atau gunakan `this.nama`
4. Cast tidak aman -> gunakan `as?` + elvis
5. @Suppress hanya untuk kasus yang sudah dipertimbangkan

Kapan Memakai @Suppress #

@Suppress adalah alat yang sah tetapi harus dipakai dengan hati-hati. Kondisi yang tepat untuk @Suppress:

  • Kompatibilitas dengan API eksternal: mis. cast Any ke List<Int> karena API Java tidak punya generic type info.
  • Kasus yang sudah dianalisis dan aman: mis. variable var yang akan dimutasi di future code yang belum diimplementasikan.
  • Generasi kode: kode yang di-generate tidak perlu warning.

Kondisi yang TIDAK tepat untuk @Suppress:

  • Menyembunyikan warning yang sebenarnya bug: mis. suppress NULLABLE_TYPE padahal null memang terjadi.
  • Menghindari refactor kecil: mis. suppress UNUSED_PARAMETER padahal parameter memang tidak diperlukan dan dapat dihapus.

Migrasi API Deprecated #

Saat compiler memberi warning DEPRECATION, langkah yang benar adalah migrasi ke API baru. Banyak API deprecated disertai annotation ReplaceWith(...) yang dapat dipakai IntelliJ untuk auto-fix: tekan ALT+ENTER pada warning, pilih “Replace with …”. Bila tidak ada ReplaceWith, baca dokumentasi API untuk memahami penggantinya.

Best Practice: Zero Warning Policy #

Banyak tim menerapkan “zero warning policy”: build gagal bila ada warning. Kebijakan ini membuat warning tidak menumpuk. Untuk proyek lama dengan banyak warning, lakukan migrasi bertahap: pasang allWarningsAsErrors = true di Gradle setelah warning yang ada diperbaiki.

kotlin Aktifkan allWarningsAsErrors di Gradle
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions {
        allWarningsAsErrors = true
    }
}

Referensi Lanjutan #

  • Diagnostics — panduan resmi diagnostics dan warning kompilator Kotlin

Penutup #

Compiler warning adalah sinyal gratis dari compiler bahwa kode mungkin bermasalah. Mengabaikan warning sama dengan menolak bantuan gratis. Pada chapter berikutnya kita akan membahas refactoring: transformasi terstruktur pada kode untuk meningkatkan kualitas tanpa mengubah perilaku, didukung oleh tool refactor bawaan IntelliJ.