Saya telah membaca bahwa adalah mungkin untuk mengimplementasikan Singleton
di Jawa menggunakan Enum
seperti:
public enum MySingleton {
INSTANCE;
}
Tetapi, bagaimana cara kerja di atas? Secara khusus, suatu Object
harus dipakai. Di sini, bagaimana MySingleton
sedang dipakai? Siapa yang melakukan new MySingleton()
?
java
design-patterns
enums
singleton
Anand
sumber
sumber
INSTANCE
sama denganpublic static final MySingleton INSTANCE = new MySingleton();
.Jawaban:
Ini,
memiliki konstruktor kosong implisit. Jelaskan secara eksplisit,
Jika Anda kemudian menambahkan kelas lain dengan
main()
metode sepertiAnda akan melihat
enum
bidang adalah kompilasi konstanta waktu, tetapi mereka adalah contoh darienum
tipe mereka . Dan, mereka dibangun ketika tipe enum direferensikan untuk pertama kalinya .sumber
private
pengubah tidak memiliki arti untukenum
konstruktor dan sepenuhnya berlebihan.Suatu
enum
tipe adalah tipe khususclass
.Wasiat Anda
enum
sebenarnya akan dikompilasi menjadi sesuatu sepertiKetika kode Anda pertama kali diakses
INSTANCE
, kelasMySingleton
akan dimuat dan diinisialisasi oleh JVM. Proses ini menginisialisasistatic
bidang di atas satu kali (malas).sumber
public enum MySingleton { INSTANCE,INSTANCE1; }
dan kemudianSystem.out.println(MySingleton.INSTANCE.hashCode()); System.out.println(MySingleton.INSTANCE1.hashCode());
mencetak kode hash yang berbeda. Apakah ini berarti dua objek MySingleton dibuat?enum
konstanta perbedaan .Dalam buku praktik terbaik Java oleh Joshua Bloch, Anda dapat menemukan alasan mengapa Anda harus menegakkan properti Singleton dengan konstruktor pribadi atau tipe Enum. Bab ini cukup panjang, jadi buatlah ringkasannya:
Membuat kelas menjadi Singleton dapat membuat sulit untuk menguji kliennya, karena tidak mungkin untuk mengganti implementasi tiruan untuk singleton kecuali jika mengimplementasikan antarmuka yang berfungsi sebagai tipenya. Pendekatan yang disarankan adalah menerapkan Singletons dengan hanya membuat tipe enum dengan satu elemen:
Pendekatan ini secara fungsional setara dengan pendekatan lapangan publik, kecuali bahwa itu lebih ringkas, menyediakan mesin serialisasi secara gratis, dan memberikan jaminan kuat terhadap berbagai instantiasi, bahkan dalam menghadapi serialisasi canggih atau serangan refleksi.
sumber
Seperti semua instance enum, Java instantiate setiap objek ketika kelas dimuat, dengan beberapa jaminan bahwa itu instantiated tepat sekali per JVM . Pikirkan
INSTANCE
deklarasi sebagai bidang final statis publik: Java akan instantiate objek saat kelas pertama kali disebut.Mesin virtual dibuat selama inisialisasi statis, yang didefinisikan dalam Spesifikasi Bahasa Jawa, bagian 12.4 .
Untuk apa nilainya, Joshua Bloch menggambarkan pola ini secara rinci sebagai item 3 dari Java Edisi Kedua yang Efektif .
sumber
Karena Pola Singleton adalah tentang memiliki konstruktor pribadi dan memanggil beberapa metode untuk mengendalikan instantiasi (seperti beberapa
getInstance
), dalam Enums kita sudah memiliki konstruktor pribadi implisit.Saya tidak tahu persis bagaimana JVM atau wadah mengontrol contoh kami
Enums
, tetapi tampaknya sudah menggunakan implisitSingleton Pattern
, bedanya adalah kami tidak memanggilgetInstance
, kami hanya memanggil Enum.sumber
Seperti, sampai batas tertentu, telah disebutkan sebelumnya, enum adalah kelas java dengan kondisi khusus yang definisinya harus dimulai dengan setidaknya satu "konstanta enum".
Selain itu, dan bahwa enum tidak dapat diperpanjang atau digunakan untuk memperluas kelas lain, enum adalah kelas seperti kelas apa pun dan Anda menggunakannya dengan menambahkan metode di bawah definisi konstan:
Anda mengakses metode singleton di sepanjang baris ini:
Penggunaan enum, alih-alih kelas, adalah, seperti yang telah disebutkan dalam jawaban lain, kebanyakan tentang instantiasi single-safe thread dan jaminan bahwa itu akan selalu hanya satu salinan.
Dan, mungkin, yang paling penting, bahwa perilaku ini dijamin oleh JVM itu sendiri dan spesifikasi Java.
Berikut adalah bagian dari spesifikasi Java tentang bagaimana beberapa instance dari instance enum dicegah:
Yang perlu diperhatikan adalah bahwa setelah instantiasi masalah keamanan thread harus ditangani seperti di kelas lain dengan kata kunci yang disinkronkan dll.
sumber