Ini berarti bahwa argumen tipe untuk enum harus berasal dari enum yang itu sendiri memiliki argumen tipe yang sama. Bagaimana ini bisa terjadi? Dengan membuat argumen type maka tipe baru itu sendiri. Jadi jika saya punya enum yang disebut StatusCode, itu akan setara dengan:
public class StatusCode extends Enum<StatusCode>
Sekarang jika Anda memeriksa kendala, kami punya Enum<StatusCode>
- jadi E=StatusCode
. Mari kita periksa: apakah E
memperpanjang Enum<StatusCode>
? Iya! Kami baik-baik saja
Anda mungkin bertanya pada diri sendiri apa gunanya ini :) Yah, itu berarti bahwa API untuk Enum dapat merujuk pada dirinya sendiri - misalnya, bisa mengatakan Enum<E>
implementasinya Comparable<E>
. Kelas dasar dapat melakukan perbandingan (dalam hal enum) tetapi dapat memastikan bahwa itu hanya membandingkan jenis enum yang tepat satu sama lain. (EDIT: Ya, hampir - lihat hasil edit di bagian bawah.)
Saya telah menggunakan sesuatu yang serupa di porta C # dari ProtocolBuffers. Ada "pesan" (tidak berubah) dan "pembangun" (bisa berubah, digunakan untuk membangun pesan) - dan mereka datang sebagai pasangan jenis. Antarmuka yang terlibat adalah:
public interface IBuilder<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
Ini berarti bahwa dari pesan Anda bisa mendapatkan pembangun yang sesuai (misalnya untuk mengambil salinan pesan dan mengubah beberapa bit) dan dari pembangun Anda bisa mendapatkan pesan yang sesuai ketika Anda selesai membangunnya. Ini adalah pekerjaan yang baik, pengguna API tidak perlu benar-benar peduli tentang ini - ini sangat rumit, dan butuh beberapa iterasi untuk sampai ke tempatnya.
EDIT: Perhatikan bahwa ini tidak menghentikan Anda dari membuat tipe aneh yang menggunakan argumen tipe yang itu sendiri tidak apa-apa, tetapi yang bukan tipe yang sama. Tujuannya untuk memberi manfaat dengan benar kasus yang daripada melindungi Anda dari kasus yang salah .
Jadi jika Enum
tidak ditangani "khusus" di Java, Anda dapat (seperti tercantum dalam komentar) membuat jenis berikut:
public class First extends Enum<First> {}
public class Second extends Enum<First> {}
Second
akan menerapkan Comparable<First>
daripada Comparable<Second>
... tapi First
itu sendiri akan baik-baik saja.