Kode yang baik tidak hanya bekerja — kode yang baik juga mudah dibaca. Konvensi penamaan adalah aturan tak tertulis yang membantu developer memahami peran sebuah identifier tanpa harus membaca seluruh kode. Kotlin Coding Conventions resmi menetapkan empat pola utama: camelCase untuk variabel dan function, PascalCase untuk class dan interface, UPPER_SNAKE_CASE untuk konstanta, serta lowercase untuk package. Pada chapter ini kita akan membedah keempat pola tersebut beserta praktik baik dan jebakan yang perlu dihindari.

Empat konvensi utama #

Tabel berikut merangkum empat pola penamaan Kotlin:

KonteksKonvensiContoh
Variabel, property, functioncamelCasenamaPengguna, hitungTotal()
Class, interface, object, enumPascalCaseclass Pengguna, interface DapatDiskon
Konstanta compile-timeUPPER_SNAKE_CASEconst val MAX_PESERTA = 50
Packagelowercase tanpa underscorecom.example.demo

camelCase untuk variabel dan function #

camelCase memulai kata pertama dengan huruf kecil dan kata berikutnya dengan huruf besar. Beberapa pedoman khusus:

  • Variabel lokal singkat boleh satu kata: i, nama, total.
  • Variabel jamak: daftarPengguna, itemTerpilih.
  • Boolean diawali is, has, can: isAktif, hasPermission, canEdit.
  • Hindari singkatan tidak jelas: gunakan konfigurasi, bukan cfg.
  • Function diawali kata kerja: hitungTotal, ambilData, verifikasiPengguna.

PascalCase untuk class dan interface #

PascalCase memulai setiap kata dengan huruf besar. Dipakai untuk class, interface, object, enum class, annotation class, dan typealias. Beberapa pedoman:

  • Class biasanya kata benda: Pengguna, Produk, Pesanan.
  • Interface sering kata sifat atau diawali Dapat-: DapatDiskon, Comparable.
  • Object singleton memakai PascalCase: Konfigurasi, CacheMemori.
  • Enum constant memakai UPPER_SNAKE_CASE: BARU, TERKIRIM, GAGAL.

UPPER_SNAKE_CASE untuk konstanta #

Konstanta compile-time (const val) memakai UPPER_SNAKE_CASE:

kotlin Konstanta UPPER_SNAKE_CASE
const val MAX_PESERTA: Int = 50
const val NAMA_APLIKASI: String = "BelajarKotlin"
const val TIMEOUT_DETIK: Int = 30

Aturan ini hanya berlaku untuk const val. Property val biasa (bukan const) tetap memakai camelCase karena nilainya tidak disematkan saat kompilasi.

Demonstrasi konvensi #

Berikut program lengkap yang menerapkan keempat konvensi:

kotlin
const val MAX_RETRY: Int = 3
const val NAMA_APLIKASI: String = "BelajarKotlin"
const val TIMEOUT_DETIK: Int = 30

class Pengguna(val namaPengguna: String, val umurPengguna: Int)

object Konfigurasi {
    const val VERSI: Int = 1
    val defaultBahasa: String = "id-ID"
}

interface DapatDiskon {
    fun terapkanDiskon(persen: Int): Double
}

data class Produk(val idProduk: Int, val hargaProduk: Int)

fun hitungTotalBelanja(hargaPerItem: Int, kuantitas: Int): Int {
    return hargaPerItem * kuantitas
}

fun main() {
    val penggunaAktif = Pengguna("Budi", 25)
    val totalBelanja = hitungTotalBelanja(hargaPerItem = 5_000, kuantitas = 4)
    val daftarProduk = listOf(
        Produk(1, 10_000),
        Produk(2, 25_000),
        Produk(3, 7_500)
    )

    println("=== Konstanta (UPPER_SNAKE_CASE) ===")
    println("MAX_RETRY      = $MAX_RETRY")
    println("NAMA_APLIKASI  = $NAMA_APLIKASI")
    println("TIMEOUT_DETIK  = $TIMEOUT_DETIK")
    println("Konfigurasi.VERSI = ${Konfigurasi.VERSI}")
    println("Konfigurasi.defaultBahasa = ${Konfigurasi.defaultBahasa}")

    println()
    println("=== camelCase (variabel dan function) ===")
    println("penggunaAktif.namaPengguna = ${penggunaAktif.namaPengguna}")
    println("penggunaAktif.umurPengguna = ${penggunaAktif.umurPengguna}")
    println("totalBelanja = $totalBelanja")
    println("hitungTotalBelanja(5000, 4) = $totalBelanja")

    println()
    println("=== PascalCase (class dan interface) ===")
    println("Class: ${Pengguna::class.simpleName}, ${Produk::class.simpleName}")
    println("Interface: ${DapatDiskon::class.simpleName}")
    println("Object: ${Konfigurasi::class.simpleName}")

    println()
    println("=== Daftar produk ===")
    for (produk in daftarProduk) {
        println("  ${produk.idProduk}: Rp${produk.hargaProduk}")
    }

    println()
    println("=== Backing field (underscore prefix) ===")
    val penyimpanan = Penyimpanan()
    println("penyimpanan.data = ${penyimpanan.data}")
    penyimpanan.tetapkan("data baru")
    println("Setelah tetapkan: ${penyimpanan.data}")
}

class Penyimpanan {
    private var _data: String = ""

    val data: String
        get() = _data

    fun tetapkan(nilai: String) {
        _data = nilai
    }
}

Output yang Dihasilkan:

text
=== Konstanta (UPPER_SNAKE_CASE) ===
MAX_RETRY      = 3
NAMA_APLIKASI  = BelajarKotlin
TIMEOUT_DETIK  = 30
Konfigurasi.VERSI = 1
Konfigurasi.defaultBahasa = id-ID

=== camelCase (variabel dan function) ===
penggunaAktif.namaPengguna = Budi
penggunaAktif.umurPengguna = 25
totalBelanja = 20000
hitungTotalBelanja(5000, 4) = 20000

=== PascalCase (class dan interface) ===
Class: Pengguna, Produk
Interface: DapatDiskon
Object: Konfigurasi

=== Daftar produk ===
  1: Rp10000
  2: Rp25000
  3: Rp7500

=== Backing field (underscore prefix) ===
penyimpanan.data = 
Setelah tetapkan: data baru

Mari kita amati baris-baris penting pada kode di atas:

  1. Baris 1-3 — konstanta compile-time (const val) memakai UPPER_SNAKE_CASE. Nama seperti MAX_RETRY dan NAMA_APLIKASI langsung memberi sinyal bahwa nilai bersifat tetap dan tidak berubah.
  2. Baris 5 (class Pengguna(val namaPengguna: String, ...)) — class Pengguna memakai PascalCase; property namaPengguna memakai camelCase.
  3. Baris 7-10 (object Konfigurasi) — object Konfigurasi (PascalCase) berisi const val VERSI (UPPER_SNAKE_CASE) dan val defaultBahasa (camelCase). Perhatikan perbedaan: yang const memakai UPPER_SNAKE; yang val biasa memakai camelCase.
  4. Baris 12-14 (interface DapatDiskon) — interface memakai PascalCase dengan kata sifat Dapat- (dapat di-diskon).
  5. Baris 16 (data class Produk) — PascalCase untuk class; camelCase untuk property idProduk, hargaProduk.
  6. Baris 18-20 (fun hitungTotalBelanja(hargaPerItem: Int, kuantitas: Int)) — function camelCase dengan kata kerja hitung; parameter camelCase.
  7. Baris 24 (val penggunaAktif = Pengguna("Budi", 25)) — variabel camelCase; pemanggilan constructor tidak memerlukan keyword new.
  8. Baris 25-26 (val totalBelanja = hitungTotalBelanja(hargaPerItem = 5_000, kuantitas = 4)) — penggunaan named arguments memperjelas maksud parameter.
  9. Baris 49-51 (class Penyimpanan) — backing field _data dengan underscore prefix. Konvensi khusus: property private internal memakai underscore, property publik tetap camelCase. Pola ini menyatakan eksplisit bahwa _data hanya pengiring internal untuk data.
  10. Baris 53-55 (val data: String get() = _data) — property publik data menyembunyikan detail implementasi _data. Pengguna class hanya melihat data (camelCase).

Backing field dengan underscore #

Pola backing field memakai underscore prefix pada variabel private dan menyediakan property publik tanpa underscore:

kotlin Backing field pattern
class Penyimpanan {
    private var _data: String = ""        // underscore prefix
    val data: String get() = _data        // property publik
}

Konvensi ini eksplisit memberi tahu pembaca bahwa _data adalah pengiring internal untuk property data. Pola ini dipakai untuk lazy initialization, validasi, atau computed property.

Aturan tambahan #

Beberapa aturan lain yang sering ditemui:

KonteksAturan
Generik parameterHuruf besar tunggal: T, E, K, V
Enum constantUPPER_SNAKE_CASE: BARU, TERKIRIM
Annotation classPascalCase, bisa diakhiri Convention: @Experimental
Companion objectPascalCase: Companion atau nama khusus

Referensi Lanjutan #

  • Coding conventions — panduan resmi konvensi penamaan Kotlin: nama variabel, fungsi, class, dan paket
  • Properties — rujukan properti Kotlin untuk konvensi penamaan val/var dan backing field

Penguasaan konvensi penamaan menutup section Variabel dan Tipe Data. Dengan pemahaman val/var, type inference, tipe data bawaan, konversi tipe, const val, scope, dan konvensi penamaan, kita siap memasuki section berikutnya yang membahas operator dan ekspresi di Kotlin.