Saat memprogram, kita sering menghadapi kebutuhan untuk membatasi kumpulan nilai valid untuk tipe data tertentu. Jadi, misalnya, hari dalam seminggu dapat memiliki 7 nilai berbeda, bulan dalam setahun dapat memiliki 12, dan musim dapat memiliki 4. Untuk mengatasi masalah seperti itu, banyak bahasa pemrograman yang diketik secara statis menyediakan tipe data khusus - pencacahan ( Anggota enum adalah turunan
Elemen
enum
). Pencacahan tidak langsung muncul di Jawa. Konstruksi bahasa khusus enum
diperkenalkan mulai dari versi 1.5. Hingga saat ini, pemrogram telah menggunakan metode lain untuk mengimplementasikan enumerasi.
konstruksi enum
Mari kita mulai dengan sebuah contoh. Mari kita jelaskanenum
tipe data untuk menyimpan musim menggunakan:
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
Nah, contoh sederhana penggunaannya:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
Hasilnya SUMMER akan dicetak ke konsol . Menurut saya contohnya sudah jelas dan tidak perlu penjelasan.
Enum adalah sebuah kelas
Dengan mendeklarasikanenum
, secara implisit kita membuat kelas turunan dari java.lang.Enum
. Secara konvensional, konstruksinya enum Season { ... }
setara dengan class Season extends java.lang.Enum { ... }
. Dan meskipun kompiler tidak mengizinkan kita untuk secara eksplisit mewarisi dari java.lang.Enum
kita, masih mudah untuk memverifikasi bahwa enum
itu diwarisi menggunakan reflection
:
System.out.println(Season.class.getSuperclass());
Berikut ini akan ditampilkan di konsol:
class java.lang.Enum
Warisan sebenarnya secara otomatis dilakukan untuk kita oleh kompiler Java. Selanjutnya, mari kita sepakat untuk memanggil kelas yang dibuat oleh kompiler untuk mengimplementasikan enumerasi sebagai kelas enum
-, dan nilai yang mungkin dari tipe enumerasi sebagai enum
elemen -a.
Anggota enum adalah turunan enum
dari kelas - yang dapat diakses secara statis
Elemen enum Season (WINTER, SPRING и т.д.)
adalah instance enum
-class yang dapat diakses secara statis Season
. Ketersediaan statisnya memungkinkan kami melakukan perbandingan menggunakan operator perbandingan referensi ==
. Contoh:
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
Nama dan nomor seri elemen enum
Seperti disebutkan sebelumnya, setiapenum
kelas mewarisi java.lang.Enum
, yang berisi sejumlah metode yang berguna untuk semua enumerasi. Contoh:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
Outputnya adalah:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
Metodenya name()
, toString()
dan ditampilkan di sini ordinal()
. Semantik metodenya jelas. Perlu dicatat bahwa metode ini enum
diwarisi dari kelas java.lang.Enum
. Mendapatkan elemen enum
dengan representasi string dari namanya Seringkali muncul tugas untuk mendapatkan elemen enum
dengan representasi stringnya. Untuk tujuan ini, di setiap enum
kelas -, kompiler secara otomatis membuat metode statis khusus: public static EnumClass valueOf(String name)
, yang mengembalikan elemen enumerasi EnumClass
dengan nama yang sama dengan name
. Contoh penggunaan:
String name = "WINTER";
Season season = Season.valueOf(name);
Sebagai hasil dari mengeksekusi kode, variabel musim akan sama dengan Season.WINTER
. Harap dicatat bahwa jika elemen tidak ditemukan, IllegalArgumentException akan dilempar , dan jika name
sama null
, NullPointerException akan dilempar . Ngomong-ngomong, hal ini sering kali terlupakan. Untuk beberapa alasan, banyak yang sangat yakin bahwa jika suatu fungsi mengambil satu argumen dan dalam kondisi tertentu memunculkan IllegalArgumentException , maka ketika meneruskannya ke sana , IllegalArgumentExceptionnull
pasti akan dilempar juga . Tapi itu bukan intinya. Ayo lanjutkan. Mendapatkan semua elemen enumerasi Terkadang Anda perlu mendapatkan daftar semua elemen kelas pada saat run time. Untuk tujuan ini, kompiler membuat metode di setiap -class . Contoh penggunaan: enum
enum
public static EnumClass[] values()
System.out.println(Arrays.toString(Season.values()));
Kami mendapatkan output berikut:
[WINTER, SPRING, SUMMER, AUTUMN]
Perhatikan bahwa baik metode valueOf()
maupun metode tidak values()
didefinisikan di kelas java.lang.Enum
. Sebaliknya, mereka secara otomatis ditambahkan oleh kompiler ketika enum
kelas - dikompilasi. Menambahkan metode Anda sendiri ke enum
-kelas Anda memiliki kesempatan untuk menambahkan metode Anda sendiri ke kelas enum
-dan elemen-elemennya: Sama, tetapi dengan polimorfisme: Contoh terakhir menunjukkan penggunaan pewarisan di enum
. Lebih lanjut tentang ini nanti. Warisanenum
di Java enum
memungkinkan Anda mengimplementasikan hierarki kelas, yang objeknya dibuat dalam satu instance dan dapat diakses secara statis. Dalam hal ini, elemen enum
dapat berisi konstruktornya sendiri. Mari kita beri contoh: Di sini kita mendeklarasikan enumerasi Type
dengan tiga elemen INT
, INTEGER
dan STRING
. Kompiler akan membuat kelas dan objek berikut:
Type
- kelas berasal darijava.lang.Enum
INT
— objek kelas 1 berasal dariType
INTEGER
— objek kelas 2 berasal dariType
STRING
— objek kelas 3 berasal dariType
Object parse(String)
dan konstruktor Type(..., boolean)
. Pada saat yang sama, objek kelas INT
, INTEGER
dan STRING
ada dalam satu salinan dan dapat diakses secara statis. Anda dapat memverifikasi ini:
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass() + " " + Type.STRING.getClass().getSuperclass());
Kami mendapatkan output berikut:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
Dapat dilihat bahwa compiler membuat sebuah kelas Type
dan 3 nested
kelas turunannya Type
.
Kelas enum yang didekompilasi dengan warisan
Untuk mempertegas hal di atas, kami sajikan pula hasil dekompilasi enumerasiType
dari contoh di atas:
Pencacahan dan polimorfisme parametrik
Pembaca mungkin bertanya-tanya: " Mengapa pencacahan Tipe di atas tidak menggunakan obat generik? " Faktanya di Jawa penggunaan obat generikenum
dilarang. Jadi contoh berikut tidak dapat dikompilasi:
enum Type<T> {}
Pelajaran lanjutan
Untuk pemahaman yang lebih mendalam tentang cara kerja enumerasi di Java, saya sarankan Anda membiasakan diri dengan kode sumber kelasjava.lang.Enum
, dan juga menggunakan dekompiler Jad untuk mempelajari kode yang dihasilkan. Selain itu, mempelajari kode sumber perpustakaan Java mutlak diperlukan untuk memahami berapa banyak mekanisme di Java yang berfungsi dan berguna sebagai referensi untuk desain berorientasi objek. Tautan ke sumber asli: http://alexander.lds.lg.ua/
GO TO FULL VERSION