Dasturlashda biz ko'pincha ma'lum bir ma'lumot turi uchun haqiqiy qiymatlar to'plamini cheklash zarurligiga duch kelamiz. Shunday qilib, masalan, haftaning kuni 7 xil qiymatga ega bo'lishi mumkin, yil oyi 12 va mavsumda 4 ta bo'lishi mumkin. Bunday muammolarni hal qilish uchun ko'plab statik tarzda yozilgan dasturlash tillari maxsus ma'lumotlar turini taqdim etadi - ro'yxatga olish (
Elementlar -classning
enum
). Sanoq Java-da darhol paydo bo'lmadi. enum
1.5 versiyasidan boshlab ixtisoslashtirilgan til konstruktsiyasi joriy etildi. Shu paytgacha dasturchilar ro'yxatlarni amalga oshirish uchun boshqa usullardan foydalanganlar.
enum tuzilishi
Keling, misol bilan boshlaylik.enum
Keling , faslni saqlash uchun ma'lumotlar turini tavsiflab beraylik :
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
Xo'sh, undan foydalanishning oddiy misoli:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
Buning natijasida SUMMER konsolga chop etiladi . Menimcha, misol aniq va tushuntirishga muhtoj emas.
Enum - bu sinf
E'lon qilish orqalienum
biz bilvosita dan olingan sinfni yaratamiz java.lang.Enum
. An'anaviy ravishda qurilish enum Season { ... }
ga teng class Season extends java.lang.Enum { ... }
. Garchi kompilyator bizdan aniq meros olishimizga ruxsat bermasa ham , uni meros qilib olganligini java.lang.Enum
tekshirish hali ham oson : enum
reflection
System.out.println(Season.class.getSuperclass());
Konsolda quyidagilar ko'rsatiladi:
class java.lang.Enum
Haqiqiy meros biz uchun Java kompilyatori tomonidan avtomatik ravishda amalga oshiriladi. Keyin, sanab o'tishni amalga oshirish uchun kompilyator tomonidan yaratilgan sinfni -class enum
va sanab o'tilgan turdagi mumkin bo'lgan qiymatlarni enum
-a elementi deb atashga rozi bo'laylik.
enum
Enum a'zolari statik ravishda kirish mumkin bo'lgan -sinf namunalari
Elementlar -classning enum Season (WINTER, SPRING и т.д.)
statik ravishda kirish mumkin bo'lgan namunalari . Ularning statik mavjudligi mos yozuvlar taqqoslash operatori yordamida taqqoslash imkonini beradi . Misol: enum
Season
==
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
Enum elementining nomi va seriya raqami
Yuqorida aytib o'tilganidek, har qandayenum
-class meros qilib oladi java.lang.Enum
, unda barcha sanablar uchun foydali bo'lgan bir qator usullar mavjud. Misol:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
Chiqish quyidagicha bo'ladi:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
Usullari name()
va bu toString()
erda ko'rsatilgan ordinal()
. Usullarning semantikasi aniq. Shuni ta'kidlash kerakki, bu usullar enum
sinfdan meros bo'lib o'tadi java.lang.Enum
. Elementni enum
uning nomining satrli tasviri bo'yichaenum
olish Ko'pincha elementni satr tasviri orqali olish vazifasi tug'iladi . Ushbu maqsadlar uchun har bir enum
sinfda kompilyator avtomatik ravishda maxsus statik usul yaratadi: , bu nomga teng bo'lgan public static EnumClass valueOf(String name)
sanab elementni qaytaradi . Foydalanish misoli: EnumClass
name
String name = "WINTER";
Season season = Season.valueOf(name);
Kodni bajarish natijasida mavsum o'zgaruvchisi ga teng bo'ladi Season.WINTER
. E'tibor bering, agar element topilmasa, IllegalArgumentException tashlanadi , agar u name
teng bo'lsa null
, NullPointerException tashlanadi . Aytgancha, bu ko'pincha unutiladi. Ba'zi sabablarga ko'ra, ko'pchilik, agar funktsiya bitta argumentni qabul qilsa va ma'lum sharoitlarda IllegalArgumentException ni tashlasa , uni u erga o'tkazishda , albatta , IllegalArgumentExceptionnull
ham tashlanadi, deb qat'iy ishonch hosil qiladi . Lekin bu gapdan boshqa narsa. Davom etaylik. Ro'yxatning barcha elementlarini olish Ba'zan ish vaqtida -classning barcha elementlari ro'yxatini olishingiz kerak bo'ladi . Ushbu maqsadlar uchun kompilyator har bir sinfda usul yaratadi . Foydalanish misoli: enum
enum
public static EnumClass[] values()
System.out.println(Arrays.toString(Season.values()));
Biz quyidagi natijani olamiz:
[WINTER, SPRING, SUMMER, AUTUMN]
E'tibor bering, sinfda na usul valueOf()
, na usul aniqlanmagan . Buning o'rniga ular -class kompilyatsiya qilinganda kompilyator tomonidan avtomatik ravishda qo'shiladi . -classga o'z usullaringizni qo'shish Siz o'z usullaringizni -classga ham, uning elementlariga ham qo'shishingiz mumkin : Xuddi shunday, lekin polimorfizm bilan: Oxirgi misolda merosdan foydalanish ko'rsatilgan . Bu haqda keyinroq. Java -da meros ob'ektlari bitta instansiyada yaratilgan va statik ravishda foydalanish mumkin bo'lgan sinf ierarxiyasini amalga oshirish imkonini beradi. Bunday holda, elementlar o'z konstruktorlarini o'z ichiga olishi mumkin. Misol keltiramiz: Bu erda biz uchta elementdan iborat sanab e'lon qilamiz va . Kompilyator quyidagi sinflar va ob'ektlarni yaratadi: values()
java.lang.Enum
enum
enum
enum
enum
enum
enum
enum
Type
INT
INTEGER
STRING
Type
-dan olingan sinfjava.lang.Enum
INT
— dan olingan 1-sinf obyektiType
INTEGER
— dan olingan 2-sinf obyektiType
STRING
— dan olingan 3-sinf obyektiType
Object parse(String)
Uchta olingan sinflar polimorfik usul va konstruktor bilan yaratiladi Type(..., boolean)
. Shu bilan birga, sinflar ob'ektlari INT
, INTEGER
va STRING
bitta nusxada mavjud va statik ravishda foydalanish mumkin. Buni tekshirishingiz mumkin:
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());
Biz quyidagi natijani olamiz:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
Ko'rinib turibdiki, kompilyator sinf va dan olingan Type
3 sinf yaratgan . nested
Type
Meros bilan dekompilyatsiya qilingan enum-sinf
Type
Yuqoridagilarni tasdiqlash uchun biz yuqoridagi misoldan sanab o'tish natijasini ham taqdim etamiz :
Sanoqlar va parametrik polimorfizm
O'quvchi hayron bo'lishi mumkin: " Nega yuqoridagi turdagi ro'yxatda generiklar ishlatilmaydi? " Gap shundaki, Java-da generiklardan foydalanishenum
taqiqlangan. Shunday qilib, quyidagi misol kompilyatsiya qilinmaydi:
enum Type<T> {}
Qo'shimcha o'rganish
Java-da ro'yxatlar qanday ishlashini chuqurroq tushunish uchun men sizga sinfning manba kodi bilan tanishishingizni tavsiya qilamanjava.lang.Enum
, shuningdek, yaratilgan kodni o'rganish uchun Jad dekompilyatoridan foydalaning. Bundan tashqari, Java kutubxonasi manba kodini o'rganish Java-da qancha mexanizm ishlashini tushunish uchun juda zarur va ob'ektga yo'naltirilgan dizayn uchun ma'lumotnoma sifatida foydalidir. Asl manbaga havola: http://alexander.lds.lg.ua/
GO TO FULL VERSION