Enum Jawa sangat bagus. Begitu juga obat generik. Tentu saja kita semua tahu keterbatasan dari yang terakhir karena jenis penghapusan. Tetapi ada satu hal yang saya tidak mengerti, Mengapa saya tidak bisa membuat enum seperti ini:
public enum MyEnum<T> {
LITERAL1<String>,
LITERAL2<Integer>,
LITERAL3<Object>;
}
Parameter tipe generik ini <T>
pada gilirannya dapat berguna di berbagai tempat. Bayangkan parameter tipe umum ke suatu metode:
public <T> T getValue(MyEnum<T> param);
Atau bahkan di kelas enum itu sendiri:
public T convert(Object o);
Contoh lebih konkret # 1
Karena contoh di atas mungkin tampak terlalu abstrak bagi sebagian orang, inilah contoh kehidupan nyata mengapa saya ingin melakukan ini. Dalam contoh ini saya ingin menggunakan
- Enum, karena dengan begitu saya dapat menyebutkan satu set kunci properti yang terbatas
- Generik, karena dengan begitu saya dapat memiliki metode-level-safety untuk menyimpan properti
public interface MyProperties {
public <T> void put(MyEnum<T> key, T value);
public <T> T get(MyEnum<T> key);
}
Contoh lebih konkret # 2
Saya memiliki enumerasi tipe data:
public interface DataType<T> {}
public enum SQLDataType<T> implements DataType<T> {
TINYINT<Byte>,
SMALLINT<Short>,
INT<Integer>,
BIGINT<Long>,
CLOB<String>,
VARCHAR<String>,
...
}
Setiap enum literal jelas akan memiliki properti tambahan berdasarkan tipe generik <T>
, sementara pada saat yang sama, menjadi enum (tidak berubah, tunggal, enumerable, dll.)
Pertanyaan:
Apakah tidak ada yang memikirkan hal ini? Apakah ini keterbatasan terkait kompiler? Mempertimbangkan fakta, bahwa kata kunci " enum " diimplementasikan sebagai gula sintaksis, mewakili kode yang dihasilkan ke JVM, saya tidak mengerti batasan ini.
Siapa yang bisa menjelaskan hal ini kepada saya? Sebelum Anda menjawab, pertimbangkan ini:
- Saya tahu jenis generik dihapus :-)
- Saya tahu ada solusi menggunakan objek Class. Mereka sedang mencari solusi.
- Jenis generik menghasilkan cast yang dihasilkan oleh kompiler dimanapun berlaku (misalnya saat memanggil metode convert ()
- Jenis generik <T> akan berada di enum. Karena itu ia diikat oleh masing-masing literal enum. Oleh karena itu kompiler akan tahu, tipe apa yang diterapkan ketika menulis sesuatu seperti
String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
- Hal yang sama berlaku untuk parameter tipe generik dalam
T getvalue()
metode ini. Kompiler dapat menerapkan tipe casting saat memanggilString string = someClass.getValue(LITERAL1)
enum
ubah idiom menjadi "typesafe enum" yang kami gunakan sebelum Java 1.5. Tiba-tiba, Anda dapat membuat parameter anggota enum Anda. Mungkin itulah yang akan saya lakukan sekarang.