Kumpulan Nilai Bernama yang Tetap
Ada nilai yang hanya masuk akal sebagai salah satu dari daftar kecil yang sudah diketahui: hari dalam seminggu, jenis kartu dalam satu dek, atau status yang bisa dimiliki sebuah pesanan. Kamu bisa memodelkannya dengan kode int (0 untuk pending, 1 untuk shipped) atau string ("PENDING", "SHIPPED"), tetapi tidak ada yang mencegah pemanggil mengirim 7 atau "PNEDING". enum menutup celah itu: tipenya sendiri hanya mengizinkan nilai yang sudah kamu deklarasikan.
Day adalah tipe yang benar-benar baru. Variabel bertipe Day bisa menyimpan tepat satu dari tujuh konstanta itu, atau null, dan tidak ada yang lain. Compiler menolak Day d = "WEDNESDAY"; maupun Day d = 2;. Jaminan itulah inti dari enum.
Setiap konstanta (Day.MONDAY, dan seterusnya) adalah satu instance yang dipakai bersama dan hanya dibuat sekali. Karena hanya ada satu MONDAY, kamu membandingkan enum dengan ==, bukan equals, karena keduanya objek yang sama.
Switch pada Enum
Enum sangat cocok dipasangkan dengan switch. Di dalam switch, kamu bahkan tidak perlu menulis nama tipe di depan setiap konstanta:
Di dalam switch, tulis case SATURDAY, bukan case Day.SATURDAY, karena Java menyimpulkan tipenya. Keuntungan besarnya dibanding switch pada string atau int adalah kalau kamu menambahkan konstanta baru nanti, IDE dan pemeriksaan kelengkapan bisa menandai setiap switch yang lupa menanganinya.
Menelusuri Setiap Konstanta
Setiap enum otomatis mendapat method static values() yang mengembalikan semua konstantanya sesuai urutan deklarasi, ditambah ordinal() yang memberikan posisi setiap konstanta, dimulai dari nol:
name() memberikan identifier konstanta sebagai String, dan values() sangat cocok untuk membuat menu atau menelusuri pilihan. Satu peringatan: jangan menyimpan ordinal() di tempat yang permanen. Kalau suatu saat ada yang mengubah urutan konstantanya, angkanya ikut bergeser dan data yang tersimpan jadi rusak. Anggap ordinal() sebagai detail implementasi, bukan ID yang stabil.
Enum Adalah Class Sungguhan: Field dan Method
Di sinilah enum Java melampaui enum di bahasa lain yang hanya berupa integer bernama. Setiap konstanta bisa membawa data yang dikirim lewat constructor, dan enum bisa punya method. Kamu menuliskan konstantanya terlebih dahulu, memberi setiap konstanta argumen constructor-nya, lalu mendeklarasikan field, constructor, dan method setelah titik koma.
Perhatikan strukturnya: konstanta ditulis paling awal dan diakhiri titik koma, lalu sisa class menyusul. Constructor-nya secara implisit private: kamu tidak akan pernah bisa menulis new Planet(...), karena satu-satunya instance yang diizinkan adalah yang dideklarasikan di bagian atas. Field final membuat setiap konstanta immutable, persis seperti yang kamu inginkan untuk singleton yang dipakai bersama.
Dari String dan Sebaliknya
Untuk mengubah string menjadi konstanta yang cocok, pakai valueOf yang dibuat otomatis:
valueOf mencocokkan nama konstanta secara persis, termasuk huruf besar kecilnya, dan melempar IllegalArgumentException kalau tidak ada yang cocok. Itulah jebakan yang umum: "shipped" tidak cocok dengan SHIPPED. Saat mem-parsing input pengguna atau data dari luar, samakan dulu huruf besar kecilnya (input.toUpperCase()) dan bungkus pemanggilannya dengan try/catch, kalau tidak programmu akan crash pada nilai salah yang pertama.
Perilaku per Konstanta
Kadang setiap konstanta perlu berperilaku berbeda, bukan hanya menyimpan data yang berbeda. Kamu bisa memberi enum sebuah abstract method dan membuat setiap konstanta menyediakan implementasinya sendiri dalam body kecil:
Ini kadang disebut pola "constant-specific method". Pola ini menggantikan switch panjang pada konstanta dengan perilaku yang langsung menempel di setiap konstanta. Kalau kamu menambahkan operasi baru, compiler memaksamu mendefinisikan apply-nya, jadi kamu tidak mungkin lupa satu kasus.
Kapan Memakai Enum
Pakai enum setiap kali sebuah nilai secara alami merupakan salah satu dari kumpulan kecil yang tetap dan sudah diketahui saat kompilasi:
- Status dalam sebuah alur kerja (
PENDING,SHIPPED,DELIVERED). - Kategori, mode, atau jenis (
READ,WRITE,EXECUTE). - Setiap tempat yang membuatmu tergoda mendefinisikan sekumpulan konstanta
public static final int. Enum memberimu nilai bernama yang sama ditambah type safety,toStringyang mudah dibaca, dan dukunganswitchsecara gratis.
Jangan pakai enum untuk kumpulan yang terbuka atau baru diketahui saat runtime (username, daftar negara yang diambil dari database). Enum sudah tertanam saat kompilasi; kalau kumpulannya berubah saat program berjalan, yang kamu butuhkan adalah collection biasa.
Berikutnya: Generics
Kamu sudah melihat values() mengembalikan Planet[], dan halaman-halaman sebelumnya memakai List<Shape>. Sintaks <...> itu adalah generics, cara Java untuk menulis satu class atau method yang bisa bekerja untuk banyak tipe sambil tetap menjaga type safety sepenuhnya. Berikutnya kita akan membedah cara kerja List<String> dan Map<K, V> dan cara menulis tipe generic milikmu sendiri.
Pertanyaan yang sering diajukan
Apa itu enum di Java?
enum adalah tipe khusus yang nilainya hanya bisa berupa salah satu dari sekumpulan konstanta bernama yang tetap, seperti Day.MONDAY atau Status.ACTIVE. Setiap konstanta adalah satu instance enum yang sudah dibuat sebelumnya. Enum memberimu type safety: method yang menerima Day hanya akan pernah menerima hari yang sungguhan, tidak pernah string yang salah ketik atau int di luar jangkauan.
Apakah enum di Java bisa punya field dan method?
Bisa. Enum adalah class yang lengkap. Kamu bisa memberi setiap konstanta argumen constructor, menyimpannya di field private final, dan menambahkan method yang memakainya. Misalnya MERCURY(3.3e23, 2.4e6) mengirim massa dan jari-jari ke constructor enum, lalu method surfaceGravity() bisa menghitung dari field-field itu.
Apa perbedaan values() dan valueOf() pada enum Java?
values() mengembalikan array berisi semua konstanta enum, sesuai urutan deklarasinya, sehingga praktis untuk menelusuri setiap pilihan. valueOf("NAME") melakukan kebalikannya: ia mencari konstanta yang namanya persis sama dengan string itu, dan melempar IllegalArgumentException kalau tidak ada yang cocok. Keduanya dibuat otomatis oleh compiler.