Enum Class

Kelas enum dengan properti dan metode.

Daftar isi

Enum class adalah kelas yang jumlah instansnya tetap, yaitu konstanta bernama yang dideklarasikan di awal badan kelas. Kotlin menuliskannya dengan kata kunci enum class, dan setiap konstanta menjadi satu-satunya instans dengan namanya. Topik ini membahas deklarasi enum class dengan properti dan metode, when yang lengkap tanpa else, serta pembacaan konstanta lewat entries dan valueOf beserta error yang muncul bila namanya salah. Contoh yang dipakai adalah arah mata angin beserta derajat kompasnya.

Himpunan konstanta yang tertutup#

Konstanta enum dinyatakan dipisahkan koma, dan daftar itu ditutup ketika badan kelas memuat anggota lain. Setiap konstanta merujuk satu instans yang dibuat sekali, sehingga dua konstanta yang berbeda selalu bernilai berbeda dan perbandingannya dapat memakai ==. Urutan konstanta pada deklarasi menentukan nilai ordinal serta urutan entries yang dibaca program. Pencetakan langsung atas sebuah konstanta menghasilkan namanya, sebagaimana tampak pada keluaran berupa teks UTARA sampai BARAT.

kotlin main.kt
enum class Arah(val derajat: Int) {
    UTARA(0), TIMUR(90), SELATAN(180), BARAT(270);

    fun berikutnya(): Arah = entries[(ordinal + 1) % entries.size]
}

fun warna(arah: Arah): String = when (arah) {
    Arah.UTARA -> "merah"
    Arah.TIMUR -> "hijau"
    Arah.SELATAN -> "biru"
    Arah.BARAT -> "kuning"
}

fun main() {
    for (arah in Arah.entries) {
        println("$arah: ${arah.derajat} derajat, warna ${warna(arah)}")
    }

    println("Setelah BARAT: ${Arah.BARAT.berikutnya()}")

    val terbaca = Arah.valueOf("SELATAN")
    println("valueOf(\"SELATAN\"): $terbaca")

    try {
        Arah.valueOf("TENGGARA")
    } catch (e: IllegalArgumentException) {
        println("Terjadi error: ${e.message}")
    }
}
bash
# atur PATH compiler Kotlin dan lokasi kotlin-stdlib
export PATH=/home/kal/my-project/tools/kotlinc/bin:/home/kal/my-project/tools/jdk-merged/bin:$PATH
export STDLIB=/home/kal/my-project/tools/kotlinc/lib/kotlin-stdlib.jar
# kompilasi main.kt menjadi out.jar
kotlinc main.kt -d out.jar
# jalankan program dengan kotlin-stdlib di classpath
java -cp "out.jar:$STDLIB" MainKt
text Keluaran
UTARA: 0 derajat, warna merah
TIMUR: 90 derajat, warna hijau
SELATAN: 180 derajat, warna biru
BARAT: 270 derajat, warna kuning
Setelah BARAT: UTARA
valueOf("SELATAN"): SELATAN
Terjadi error: No enum constant Arah.TENGGARA

Perulangan pada fungsi main membaca Arah.entries, yaitu daftar seluruh konstanta dalam urutan deklarasinya. Setiap konstanta dicetak lengkap dengan properti derajat dan warna pilihannya dari fungsi warna. Pemanggilan berikutnya() pada BARAT kembali ke UTARA, karena perhitungannya memutar kembali ke awal daftar. Baris terakhir menunjukkan valueOf("SELATAN") berhasil, sedangkan valueOf("TENGGARA") berakhir sebagai error yang ditangkap blok try, dan kedua perilaku itu dibahas pada bagian akhir.

Properti dan metode pada enum class#

Enum class dapat membawa properti dan metode seperti kelas pada umumnya. Properti dinyatakan pada konstruktor utama, lalu setiap konstanta mengirimkan nilainya sendiri, seperti UTARA(0) yang menyimpan derajat 0. Karena propertinya bagian dari konstanta, nilainya dapat dibaca dari konstanta mana pun, misalnya Arah.TIMUR.derajat.

Metode dinyatakan di badan kelas dan dapat mengakses properti maupun ordinal, yaitu posisi konstanta dalam urutan deklarasi yang dimulai dari 0. Konstanta tertentu juga boleh memiliki badan sendiri yang meng-override metodenya, sehingga perilaku dua konstanta dapat dibuat berbeda bila memang diperlukan. Fungsi berikutnya pada program di atas menghitung indeks berikutnya dengan operasi sisa bagi, sehingga daftar arah berputar tanpa pernah keluar dari batasnya. Satu aturan penulisan perlu diperhatikan, yaitu tanda titik koma wajib menutup daftar konstanta sebelum anggota pertama dinyatakan. Tanpa tanda itu, compiler menganggap badan kelas masih bagian dari daftar konstanta dan menolaknya.

when tanpa else atas enum#

Fungsi warna pada program di atas memakai when sebagai ekspresi yang hasilnya langsung dikembalikan. Keempat konstanta mendapat cabangnya masing-masing, sehingga tidak ada else yang diperlukan. Compiler mengetahui seluruh konstanta Arah dan menuntut setiap konstanta ditangani. Bila satu cabang dihapus, kompilasi ditolak dengan pesan 'when' expression must be exhaustive. Add the 'BARAT' branch or an 'else' branch. yang menyebut cabang yang masih kurang.

Sifat ini menempatkan when atas enum pada posisi yang sama dengan when atas sealed class. Keduanya mengubah penambahan nilai baru menjadi sinyal saat kompilasi, bukan cacat yang muncul saat program berjalan. Konstanta baru yang ditambahkan langsung memunculkan daftar titik penanganan yang belum mengolahnya. Kebiasaan menulis cabang lengkap tanpa else membuat compiler ikut menjaga konsistensi setiap kali himpunan konstanta diperluas, dan pembandingan antarkonstanta cukup memakai == karena jumlah instansnya tetap. Cabang yang hasilnya sama pula boleh digabung dengan koma, misalnya Arah.UTARA, Arah.BARAT -> ..., sehingga penulisan tetap ringkas.

entries, values, dan valueOf#

entries adalah daftar konstanta enum yang efisien dan stabil digunakan sejak Kotlin 1.9, dan bentuk inilah yang dipakai pada program di atas. Bentuk warisannya adalah fungsi values() yang mengembalikan Array dan tetap tersedia untuk kode lama. Bentuk itu masih banyak dipakai pada proyek yang sudah berjalan, sehingga mengenalinya tetap berguna ketika membaca kode warisan. Untuk kode baru, entries menjadi pilihan baku karena tipe datanya sama dengan collection Kotlin pada umumnya. Setiap konstanta juga membawa properti name yang menyediakan namanya dalam bentuk String.

Fungsi valueOf menerima nama konstanta dan mengembalikan instansnya. Pencocokannya bersifat persis, sehingga huruf kecil, spasi, maupun nama yang tidak terdaftar ditolak. Penolakan itu berupa IllegalArgumentException dengan pesan No enum constant Arah.TENGGARA, sebagaimana tampak pada keluaran program. Karena alasan itu, nama yang berasal dari masukan luar sebaiknya dibaca di dalam blok try dengan penanganan yang jelas, atau dicocokkan terlebih dahulu terhadap daftar entries sebelum valueOf dipanggil.

Ringkasan#

  • enum class membatasi instans pada konstanta bernama yang dideklarasikan di awal badan kelas, dengan satu instans per konstanta.
  • Enum dapat membawa properti lewat konstruktor utama dan metode di badan kelas, dengan tanda titik koma yang menutup daftar konstanta bila ada anggota.
  • when atas enum wajib lengkap dan dapat ditulis tanpa else, sehingga konstanta baru menagih pembaruan seluruh titik penanganan.
  • entries menjadi cara baku membaca daftar konstanta sejak Kotlin 1.9, sedangkan valueOf menolak nama yang tidak terdaftar dengan IllegalArgumentException.

Referensi#