Hari ini saya sedang menelusuri beberapa pertanyaan di situs ini dan saya menemukan sebuah penyebutan enum
yang digunakan dalam pola tunggal tentang manfaat keamanan utas yang diakui untuk solusi tersebut.
Saya tidak pernah menggunakan enum
dan saya telah memprogram di Jawa selama lebih dari beberapa tahun sekarang. Dan ternyata mereka banyak berubah. Sekarang mereka bahkan melakukan dukungan penuh OOP dalam diri mereka sendiri.
Jawaban:
Anda harus selalu menggunakan enum ketika suatu variabel (terutama parameter metode) hanya dapat mengambil satu dari sekumpulan nilai yang mungkin. Contohnya adalah hal-hal seperti konstanta tipe (status kontrak: "permanen", "temp", "magang"), atau bendera ("jalankan sekarang", "penundaan eksekusi").
Jika Anda menggunakan enum alih-alih bilangan bulat (atau kode String), Anda meningkatkan pemeriksaan waktu kompilasi dan menghindari kesalahan dari memasukkan konstanta yang tidak valid, dan Anda mendokumentasikan nilai mana yang legal untuk digunakan.
BTW, terlalu sering menggunakan enum dapat berarti bahwa metode Anda melakukan terlalu banyak (seringkali lebih baik untuk memiliki beberapa metode terpisah, daripada satu metode yang menggunakan beberapa flag yang memodifikasi apa yang dilakukannya), tetapi jika Anda harus menggunakan flag atau kode jenis, enum adalah cara untuk pergi.
Sebagai contoh, mana yang lebih baik?
melawan
Panggilan metode seperti:
kemudian menjadi:
Dalam contoh kedua, segera jelas jenis mana yang diizinkan, dokumen dan implementasi tidak dapat disinkronkan, dan kompiler dapat menegakkan ini. Juga, panggilan yang tidak valid seperti
tidak mungkin lagi.
sumber
you should *always* use enums when a variable can only take one out of a small set of possible values
. Menggunakan nilai-nilai konstan sebagai 'bendera biner' (dengan logikaor
) dapat berguna untuk aplikasi waktu nyata di mana Anda kekurangan memori.Mengapa menggunakan fitur bahasa pemrograman? Alasan kami memiliki bahasa sama sekali adalah untuk
Enum meningkatkan kemungkinan kebenaran dan keterbacaan tanpa menulis banyak boilerplate. Jika Anda ingin menulis boilerplate, maka Anda dapat "mensimulasikan" enum:
Sekarang Anda dapat menulis:
Pelat di atas memiliki efek yang sama dengan
Keduanya memberikan tingkat bantuan pemeriksaan yang sama dari kompiler. Boilerplate lebih banyak mengetik. Tetapi menghemat banyak mengetik membuat programmer lebih efisien (lihat 1), jadi ini adalah fitur yang bermanfaat.
Ini bermanfaat untuk setidaknya satu alasan lagi, juga:
Ganti pernyataan
Satu hal yang tidak diberikan
static final
simulasi enum di atas adalah case yang bagus . Untuk tipe enum, Java switch menggunakan tipe variabelnya untuk menyimpulkan lingkup kasus enum, jadi untuk hal di atas Anda hanya perlu mengatakan:switch
enum Color
Perhatikan itu tidak ada
Color.RED
dalam kasing. Jika Anda tidak menggunakan enum, satu-satunya cara untuk menggunakan jumlah bernama denganswitch
sesuatu seperti:Tapi sekarang variabel untuk menahan warna harus memiliki tipe
int
. Kompiler memeriksa enum danstatic final
simulasi hilang. Tidak senang.Kompromi adalah menggunakan anggota bernilai skalar dalam simulasi:
Sekarang:
Tetapi perhatikan, bahkan lebih banyak lagi boilerplate!
Menggunakan enum sebagai singleton
Dari pelat ketel di atas, Anda dapat melihat mengapa enum menyediakan cara untuk mengimplementasikan singleton. Alih-alih menulis:
dan kemudian mengaksesnya dengan
kita bisa katakan saja
yang memberi kita hal yang sama. Kami bisa lolos dengan ini karena enum Java yang diimplementasikan sebagai kelas penuh dengan hanya sintaksis gula sedikit ditaburi di atas. Lagi-lagi ini kurang matang, tetapi tidak jelas kecuali jika idiomnya sudah Anda kenal. Saya juga tidak suka fakta bahwa Anda mendapatkan berbagai fungsi enum meskipun mereka tidak masuk akal untuk singleton:
ord
danvalues
, dll. (Sebenarnya ada simulasi yang lebih rumit di manaColor extends Integer
itu akan bekerja dengan switch, tapi itu sangat rumit sehingga bahkan lebih rumit jelas menunjukkan mengapaenum
itu ide yang lebih baik.)Keamanan benang
Keamanan utas merupakan masalah potensial hanya saat singleton dibuat malas tanpa penguncian.
Jika banyak utas memanggil
getInstance
secara bersamaan saatINSTANCE
masih nol, sejumlah instance dapat dibuat. Ini buruk. Satu-satunya solusi adalah menambahkansynchronized
akses untuk melindungi variabelINSTANCE
.Namun,
static final
kode di atas tidak memiliki masalah ini. Ini menciptakan instance dengan penuh semangat pada waktu pemuatan kelas. Pemuatan kelas disinkronkan.The
enum
tunggal secara efektif malas karena tidak diinisialisasi sampai digunakan pertama. Inisialisasi Java juga disinkronkan, jadi beberapa utas tidak dapat menginisialisasi lebih dari satu instanceINSTANCE
. Anda mendapatkan singleton diinisialisasi malas dengan kode yang sangat sedikit. Satu-satunya negatif adalah sintaks yang agak kabur. Anda perlu mengetahui idiom atau memahami sepenuhnya bagaimana pemuatan kelas dan inisialisasi bekerja untuk mengetahui apa yang terjadi.sumber
static final
bidang diinisialisasi pada waktu inisialisasi kelas , bukan waktu memuat. Persis sama denganenum
inisialisasi konstan (pada kenyataannya, mereka identik di bawah tenda). Itu sebabnya mencoba menerapkan kode inisialisasi malas "pintar" untuk lajang selalu sia-sia, bahkan dalam versi Java pertama.Selain kasus penggunaan yang telah disebutkan, saya sering menemukan enum berguna untuk menerapkan pola strategi, mengikuti beberapa pedoman OOP dasar:
Contoh paling sederhana adalah seperangkat
Comparator
implementasi:"Pola" ini dapat digunakan dalam skenario yang jauh lebih kompleks, memanfaatkan secara luas semua barang yang datang dengan enum: iterasi pada instance, mengandalkan urutan implisit mereka, mengambil sebuah instance dengan namanya, metode statis menyediakan instance yang tepat untuk konteks tertentu dll. Dan Anda masih memiliki semua ini tersembunyi di balik antarmuka sehingga kode Anda akan bekerja dengan implementasi kustom tanpa modifikasi jika Anda menginginkan sesuatu yang tidak tersedia di antara "opsi default".
Saya telah melihat ini berhasil diterapkan untuk memodelkan konsep waktu granularity (harian, mingguan, dll) di mana semua logika dirangkum dalam enum (memilih granularity yang tepat untuk rentang waktu tertentu, perilaku spesifik terikat ke setiap granularity sebagai konstan metode dll.). Dan masih,
Granularity
seperti yang terlihat oleh lapisan layanan hanyalah sebuah antarmuka.sumber
CASE_INSENSITIVE { @Override public int compare(String s1, String s2) { return s1.compareToIgnoreCase(s2); }
. Satu keuntungan yang belum disebutkan adalah bahwa Anda mendapatkan dukungan Serialisasi yang kuat; formulir persisten hanya berisi nama kelas dan nama konstan, tidak tergantung pada detail implementasi komparator Anda.Sesuatu yang tidak ada dari jawaban lain yang dibahas yang membuat enum sangat kuat adalah kemampuan untuk memiliki metode templat . Metode dapat menjadi bagian dari base enum dan diganti oleh masing-masing jenis. Dan, dengan perilaku yang melekat pada enum, sering menghilangkan kebutuhan untuk jika-membangun atau beralih pernyataan seperti yang ditunjukkan posting blog ini - di mana
enum.method()
apa yang awalnya akan dieksekusi di dalam kondisi. Contoh yang sama juga menunjukkan penggunaan impor statis dengan enum serta menghasilkan kode seperti DSL yang jauh lebih bersih.Beberapa kualitas menarik lainnya termasuk fakta bahwa enum menyediakan implementasi untuk
equals()
,toString()
danhashCode()
dan mengimplementasikanSerializable
danComparable
.Untuk rundown lengkap dari semua yang ditawarkan enum, saya sangat merekomendasikan Bruce Eckel's Thinking in Java edisi ke 4 yang mencurahkan seluruh bab untuk topik ini. Terutama menerangi adalah contoh-contoh yang melibatkan permainan Rock, Paper, Scissors (yaitu RoShamBo) sebagai enum.
sumber
Dari dokumen Java -
Contoh umum adalah mengganti kelas dengan seperangkat konstanta int akhir statis privat (dalam jumlah konstanta yang wajar) dengan tipe enum. Pada dasarnya jika Anda pikir Anda tahu semua nilai yang mungkin dari "sesuatu" pada waktu kompilasi Anda dapat menyatakan bahwa sebagai tipe enum. Enum memberikan keterbacaan dan fleksibilitas atas kelas dengan konstanta.
Beberapa keunggulan lain yang bisa saya pikirkan tentang jenis enum. Mereka selalu merupakan salah satu contoh dari kelas enum tertentu (maka konsep menggunakan enum sebagai singleton tiba). Keuntungan lain adalah Anda dapat menggunakan enums sebagai jenis dalam pernyataan switch-case. Anda juga dapat menggunakan toString () pada enum untuk mencetaknya sebagai string yang dapat dibaca.
sumber
DayOfWeek
enum sekarang telah ditentukan sebelumnya, dibangun ke dalam Java 8 dan kemudian sebagai bagian dari kerangka kerja java.time (dan kembali-porting ke Java 6 & 7 dan ke Android ).Anda dapat menggunakan Enum untuk mewakili konstanta tetap yang bertubuh kecil atau mode kelas internal sambil meningkatkan keterbacaan. Juga, Enums dapat menegakkan kekakuan tertentu ketika digunakan dalam parameter metode. Mereka menawarkan kemungkinan menarik untuk menyampaikan informasi ke konstruktor seperti pada contoh Planet di situs Oracle dan, seperti yang Anda temukan, juga memungkinkan cara sederhana untuk membuat pola tunggal.
mis:
Locale.setDefault(Locale.US)
membaca lebih baik daripadaLocale.setDefault(1)
dan menegakkan penggunaan set nilai tetap yang ditunjukkan dalam IDE ketika Anda menambahkan.
pemisah dan bukan semua bilangan bulat.sumber
Enum
s sebutkan seperangkat nilai tetap, dengan cara mendokumentasikan diri.Mereka membuat kode Anda lebih eksplisit, dan juga lebih sedikit rawan kesalahan.
Mengapa tidak menggunakan
String
, atauint
, alih-alihEnum
, untuk konstanta?if
) untuk memastikan argumen Anda dalam kisaran yang valid.String
s, bagaimanapun (ini tergantung pada kompleksitasnyaEnum
).Selain itu, masing-masing
Enum
instance adalah kelas, di mana Anda dapat mendefinisikan perilaku individualnya.Plus, mereka menjamin keamanan thread saat membuat instance (ketika enum dimuat), yang telah melihat aplikasi hebat dalam menyederhanakan Pola Singleton .
Blog ini menggambarkan beberapa aplikasi, seperti Mesin Negara untuk parser.
sumber
Sangat berguna untuk mengetahui bahwa
enums
sama seperti kelas lain denganConstant
bidang dan aprivate constructor
.Sebagai contoh,
Kompiler mengkompilasinya sebagai berikut;
sumber
enum
berarti enum eration yaitu menyebutkan (sejumlah hal) satu per satu.ATAU
Sebagai contoh:
Keuntungan enum:
untuk lebih
sumber
Apa itu enum
Mengapa menggunakan enum
Catatan
sumber
Terlepas dari semua yang dikatakan oleh orang lain .. Dalam proyek yang lebih tua yang saya gunakan untuk bekerja, banyak komunikasi antara entitas (aplikasi independen) menggunakan bilangan bulat yang mewakili satu set kecil. Itu berguna untuk mendeklarasikan set
enum
dengan metode statis untuk mendapatkanenum
objek darivalue
dan sebaliknya. Kode tampak lebih bersih, beralih kegunaan huruf besar dan menulis lebih mudah ke log.Buat
enum
objek dari nilai yang diterima (misalnya 1,2) menggunakanProtocolType.fromInt(2)
Tulis ke log menggunakanmyEnumObj.name
Semoga ini membantu.
sumber
Enum mewarisi semua metode
Object
kelas dan kelas abstrakEnum
. Jadi Anda dapat menggunakan metode itu untuk refleksi, multithreading, serilisasi, sebanding, dll. Jika Anda hanya mendeklarasikan konstanta statis bukan Enum, Anda tidak bisa. Selain itu, nilai Enum dapat dikirimkan ke lapisan DAO juga.Berikut ini contoh program untuk diperagakan.
sumber
ENum adalah singkatan dari "Enumerated Type". Ini adalah tipe data yang memiliki konstanta yang Anda tentukan sendiri.
sumber
Menurut pendapat saya, semua jawaban yang Anda jawab sekarang valid, tetapi dalam pengalaman saya, saya akan mengungkapkannya dalam beberapa kata:
Gunakan enums jika Anda ingin kompiler memeriksa validitas nilai pengidentifikasi.
Jika tidak, Anda dapat menggunakan string seperti biasa (mungkin Anda mendefinisikan beberapa "konvensi" untuk aplikasi Anda) dan Anda akan sangat fleksibel ... tetapi Anda tidak akan mendapatkan keamanan 100% terhadap kesalahan ketik pada string Anda dan Anda hanya akan menyadarinya dalam runtime.
sumber
Gunakan enums untuk TYPE SAFETY, ini adalah fitur bahasa sehingga Anda biasanya akan mendapatkan:
Enums dapat memiliki metode, konstruktor, Anda bahkan dapat menggunakan enums di dalam enums dan menggabungkan enums dengan antarmuka.
Anggap enum sebagai tipe untuk menggantikan set konstanta int yang terdefinisi dengan baik (yang Java 'warisi' dari C / C ++) dan dalam beberapa kasus untuk menggantikan bit flag.
Buku Effective Java 2nd Edition memiliki seluruh bab tentang mereka dan membahas lebih detail. Juga lihat posting Stack Overflow ini .
sumber
Java memungkinkan Anda membatasi variabel untuk memiliki salah satu dari hanya beberapa nilai yang telah ditentukan - dengan kata lain, satu nilai dari daftar yang disebutkan. Menggunakan
enums
dapat membantu mengurangi bug dalam kode Anda. Berikut ini contoh dienums
luar kelas:Hal ini membatasi
coffeesize
untuk memiliki baik:BIG
,HUGE
, atauOVERWHELMING
sebagai variabel.sumber
Enum? Mengapa harus digunakan? Saya pikir itu lebih dipahami ketika Anda akan menggunakannya. Saya memiliki pengalaman yang sama.
Katakanlah Anda memiliki operasi buat, hapus, edit, dan baca basis data.
Sekarang jika Anda membuat enum sebagai operasi:
Sekarang, Anda dapat mendeklarasikan sesuatu seperti:
Jadi Anda bisa menggunakannya dengan banyak cara. Itu selalu baik untuk memiliki enum untuk hal-hal tertentu karena operasi database pada contoh di atas dapat dikontrol dengan memeriksa operasi saat ini . Mungkin orang bisa mengatakan ini bisa diselesaikan dengan variabel dan nilai integer juga. Tapi saya percaya Enum adalah cara yang lebih aman dan programmer.
Hal lain: Saya pikir setiap programmer menyukai boolean , bukan? Karena hanya dapat menyimpan dua nilai, dua nilai spesifik. Jadi Enum dapat dianggap memiliki jenis fasilitas yang sama di mana pengguna akan menentukan berapa banyak dan jenis nilai apa yang akan disimpan, hanya dengan cara yang sedikit berbeda. :)
sumber
Sejauh ini, saya tidak pernah perlu menggunakan enum. Saya telah membaca tentang mereka sejak mereka diperkenalkan dalam versi 1,5 atau harimau seperti yang disebut kembali pada hari itu. Mereka tidak pernah benar-benar memecahkan 'masalah' bagi saya. Bagi mereka yang menggunakannya (dan saya melihat banyak dari mereka melakukan), yakin itu pasti melayani beberapa tujuan. Hanya 2 pound saya.
sumber
Ada banyak jawaban di sini, hanya ingin menunjukkan dua yang spesifik:
1) Menggunakan sebagai konstanta dalam
Switch-case
pernyataan. Switch case tidak memungkinkan Anda untuk menggunakan objek String untuk case. Enum berguna. Lebih lanjut: http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/2) Implementing
Singleton Design Pattern
- Enum lagi, datang untuk menyelamatkan. Penggunaan, di sini: Apa pendekatan terbaik untuk menggunakan Enum sebagai singleton di Jawa?sumber
Yang memberi saya momen Ah-Ha adalah realisasi ini: bahwa Enum memiliki konstruktor pribadi yang hanya dapat diakses melalui pencacahan publik:
sumber
Bagi saya untuk membuat kode dapat dibaca di masa depan, kasus enumerasi aplyable yang paling berguna diwakili dalam cuplikan berikutnya:
sumber
Dalam pengalaman saya, saya telah melihat penggunaan Enum terkadang menyebabkan sistem menjadi sangat sulit untuk diubah. Jika Anda menggunakan Enum untuk serangkaian nilai spesifik domain yang sering berubah, dan memiliki banyak kelas dan komponen lain yang bergantung padanya, Anda mungkin ingin mempertimbangkan untuk tidak menggunakan Enum.
Misalnya, sistem perdagangan yang menggunakan Enum untuk pasar / pertukaran. Ada banyak pasar di luar sana dan hampir pasti akan ada banyak sub-sistem yang perlu mengakses daftar pasar ini. Setiap kali Anda ingin pasar baru ditambahkan ke sistem Anda, atau jika Anda ingin menghapus pasar, semua yang ada di bawah matahari harus dibangun kembali dan dilepaskan.
Contoh yang lebih baik adalah sesuatu seperti jenis kategori produk. Katakanlah perangkat lunak Anda mengelola inventaris untuk department store. Ada banyak kategori produk, dan banyak alasan mengapa daftar kategori ini dapat berubah. Manajer mungkin ingin menyediakan lini produk baru, menyingkirkan lini produk lain, dan mungkin mengatur ulang kategori dari waktu ke waktu. Jika Anda harus membangun kembali dan memindahkan semua sistem Anda hanya karena pengguna ingin menambahkan kategori produk, maka Anda telah mengambil sesuatu yang seharusnya sederhana dan cepat (menambahkan kategori) dan membuatnya sangat sulit dan lambat.
Intinya, Enums baik jika data yang Anda wakili sangat statis dari waktu ke waktu dan memiliki jumlah dependensi yang terbatas. Tetapi jika data banyak berubah dan memiliki banyak dependensi, maka Anda memerlukan sesuatu yang dinamis yang tidak diperiksa pada waktu kompilasi (seperti tabel database).
sumber
Singleton berbasis enum
Pendekatan ini mengimplementasikan singleton dengan mengambil keuntungan dari jaminan Java bahwa setiap nilai enum hanya dipakai satu kali dalam program Java dan enum memberikan dukungan implisit untuk keselamatan benang. Karena nilai Java enum dapat diakses secara global, sehingga dapat digunakan sebagai singleton.
Bagaimana cara kerjanya? Nah, baris dua kode dapat dianggap sesuatu seperti ini:
Dan kita mendapatkan singleton awal awal yang bagus.
Ingatlah bahwa karena ini adalah enum, Anda juga selalu dapat mengakses instance via
KeuntunganSingleton.INSTANCE
:valueOf
metode digunakan dengan nama deserialisasi untuk mendapatkan contoh yang diinginkan.Enum
kelas java . Alasan bahwa refleksi tidak dapat digunakan untuk instantiate objek dari tipe enum adalah karena spesifikasi java tidak diizinkan dan aturan tersebut dikodekan dalam implementasinewInstance
metodeConstructor
kelas, yang biasanya digunakan untuk membuat objek melalui refleksi:map
. Alih-alih memiliki satu instance per aplikasi (misalnyajava.lang.Runtime
), pola multiton bukannya memastikan satu instance per kunci .Ada beberapa realisasi pola tunggal masing-masing dengan kelebihan dan kekurangan.
Deskripsi mendetail masing-masing dari mereka terlalu bertele-tele jadi saya hanya menaruh tautan ke artikel yang bagus - Yang ingin Anda ketahui tentang Singleton
sumber
Saya akan menggunakan enum sebagai instrumen pemetaan yang berguna, menghindari beberapa
if-else
asalkan beberapa metode diterapkan.Jadi metodenya
by(String label)
memungkinkan Anda untuk mendapatkan nilai yang dihitung dengan non-disebutkan. Selanjutnya, seseorang dapat menemukan pemetaan antara 2 enum. Bisa juga mencoba '1 ke banyak' atau 'banyak ke banyak' selain hubungan default 'satu ke satu'Pada akhirnya,
enum
adalah kelas Java. Jadi, Anda dapat memilikimain
metode di dalamnya, yang mungkin berguna ketika perlu melakukan beberapa operasi pemetaanargs
segera.sumber
Alih-alih membuat banyak deklarasi const int
Anda dapat mengelompokkan semuanya dalam 1 enum
Jadi semuanya diatur oleh kelompok umum tempat mereka berada
sumber
Enum seperti kelas. Seperti kelas, ia juga memiliki metode dan atribut.
Perbedaan dengan kelas adalah: 1. konstanta enum bersifat publik, statis, final. 2. enum tidak dapat digunakan untuk membuat objek dan itu tidak dapat memperluas kelas lain. Tetapi dapat mengimplementasikan antarmuka.
sumber
Selain @BradB Jawab:
Itu sangat benar ... Aneh bahwa itu adalah satu-satunya jawaban yang menyebutkan itu. Ketika pemula menemukan enum, mereka dengan cepat menganggapnya sebagai trik sulap untuk pengidentifikasi pengenal yang valid untuk kompiler. Dan ketika kode itu dimaksudkan untuk digunakan pada sistem terdistribusi, mereka menangis ... beberapa bulan kemudian. Mempertahankan kompatibilitas ke belakang dengan enum yang berisi daftar nilai yang tidak statis adalah masalah nyata, dan menyakitkan. Ini karena ketika Anda menambahkan nilai ke enum yang ada, tipenya berubah (meskipun namanya tidak).
"Ho, tunggu, ini mungkin terlihat seperti tipe yang sama, kan? Lagipula, mereka enum dengan nama yang sama - dan bukankah enums hanya bilangan bulat di bawah tenda?" Dan untuk alasan ini, kompiler Anda kemungkinan tidak akan menandai penggunaan satu definisi dari tipe itu sendiri di mana ia mengharapkan yang lain. Tetapi pada kenyataannya, mereka (dalam cara yang paling penting) adalah tipe yang berbeda. Yang paling penting, mereka memiliki domain data yang berbeda - nilai yang dapat diterima mengingat jenisnya. Dengan menambahkan nilai, kami telah secara efektif mengubah jenis enum dan karenanya merusak kompatibilitas.
Kesimpulannya: Gunakan saat Anda inginkan, tetapi, harap periksa apakah domain data yang digunakan adalah kumpulan yang terbatas, sudah dikenal, dan telah diperbaiki .
sumber