Beberapa masalah dengan lajang enum:
Berkomitmen pada strategi implementasi
Biasanya, "singleton" mengacu pada strategi implementasi, bukan spesifikasi API. Sangat jarang untuk Foo1.getInstance()secara terbuka menyatakan bahwa itu akan selalu mengembalikan contoh yang sama. Jika diperlukan, implementasi Foo1.getInstance()dapat berkembang, misalnya, untuk mengembalikan satu instance per utas.
Dengan Foo2.INSTANCEkita secara terbuka menyatakan bahwa hal ini adalah dengan contoh, dan tidak ada kesempatan untuk mengubah itu. Strategi implementasi memiliki satu contoh terbuka dan berkomitmen untuk.
Masalah ini tidak melumpuhkan. Misalnya, Foo2.INSTANCE.doo()dapat mengandalkan objek pembantu lokal utas, untuk secara efektif memiliki instance per-utas.
Memperluas kelas Enum
Foo2memperluas kelas super Enum<Foo2>. Kami biasanya ingin menghindari kelas super; terutama dalam kasus ini, kelas super yang dipaksakan Foo2tidak ada hubungannya dengan apa Foo2yang seharusnya. Itu adalah polusi pada jenis hierarki aplikasi kita. Jika kita benar-benar menginginkan kelas super, biasanya kelas aplikasi, tetapi kita tidak bisa, Foo2kelas supernya sudah diperbaiki.
Foo2mewarisi beberapa metode contoh lucu seperti name(), cardinal(), compareTo(Foo2), yang hanya membingungkan Foo2pengguna. Foo2tidak dapat memiliki name()metode sendiri bahkan jika metode itu diinginkan dalam Foo2antarmuka.
Foo2 juga mengandung beberapa metode statis lucu
public static Foo2[] values() { ... }
public static Foo2 valueOf(String name) { ... }
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
yang tampaknya tidak masuk akal bagi pengguna. Singleton biasanya tidak seharusnya memiliki metode statis pulbic (selain dari getInstance())
Serializability
Sangat umum bagi lajang untuk menyatakan diri. Lajang ini umumnya tidak boleh serial. Saya tidak bisa memikirkan contoh realistis di mana masuk akal untuk mengangkut singleton stateful dari satu VM ke VM lain; singleton berarti "unik di dalam VM", bukan "unik di alam semesta".
Jika serialisasi benar-benar masuk akal untuk singleton stateful, singleton harus secara eksplisit dan tepat menentukan apa artinya deserialisasi singleton di VM lain di mana singleton dari tipe yang sama mungkin sudah ada.
Foo2secara otomatis berkomitmen pada strategi serialisasi / deserialisasi sederhana. Itu hanya kecelakaan yang menunggu untuk terjadi. Jika kita memiliki pohon data yang secara konseptual merujuk variabel keadaan Foo2dalam VM1 di t1, melalui serialisasi / deserialisasi nilai menjadi nilai yang berbeda - nilai variabel yang sama Foo2di dalam VM2 di t2, membuat sulit untuk mendeteksi bug. Bug ini tidak akan terjadi pada yang tidak dapat digunakan Foo1diam-diam.
Batasan pengkodean
Ada hal yang bisa dilakukan di kelas normal, tetapi dilarang di enumkelas. Misalnya, mengakses bidang statis di konstruktor. Programmer harus lebih berhati-hati karena dia bekerja di kelas khusus.
Kesimpulan
Dengan membonceng enum, kami menyimpan 2 baris kode; tetapi harga terlalu tinggi, kita harus membawa semua kantong dan pembatasan enum, kita secara tidak sengaja mewarisi "fitur" enum yang memiliki konsekuensi yang tidak diinginkan. Satu-satunya keuntungan yang diduga - serializability otomatis - ternyata menjadi kerugian.