Программалоодо биз көп учурда белгилүү бир маалымат түрү үчүн жарактуу маанилердин топтомун чектөө зарылдыгына туш болобуз. Ошентип, мисалы, жуманын күнү 7 түрдүү мааниге ээ болушу мүмкүн, жылдын айы 12, ал эми сезон 4 болушу мүмкүн. Мындай көйгөйлөрдү чечүү үчүн көптөгөн статикалык терилген программалоо тилдери атайын маалымат түрүн беришет - санап (
Элементтер -класстын
enum
). Санак Java дароо эле пайда болгон жок. 1.5 versionсынан баштап адистештирилген тил конструкциясы enum
киргизилген. Ушул учурга чейин, программисттер санап ишке ашыруу үчүн башка ыкмаларды колдонушкан.
enum куруу
Келгиле, бир мисал менен баштайлы. Төмөнкү колдонуу мененenum
жылдын убактысын сактоо үчүн маалымат түрүн сүрөттөп көрөлү:
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
Ооба, аны колдонуунун жөнөкөй мисалы:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
Натыйжада ЖАЙ консолуна басып чыгарылат . Мисал ачык-айкын жана түшүндүрүүнүн кереги жок деп ойлойм.
Энум класс болуп саналат
Жарыялоо мененenum
биз кыйыр түрдө класстан алынган классты түзөбүз java.lang.Enum
. Шарттуу түрдө курулуш enum Season { ... }
ге барабар class Season extends java.lang.Enum { ... }
. Ал эми компилятор бизге ачык мурастоого жол бербесе да , анын мураска алынгандыгын java.lang.Enum
текшерүү оңой : enum
reflection
System.out.println(Season.class.getSuperclass());
Консолдо төмөнкүлөр көрсөтүлөт:
class java.lang.Enum
Чыныгы мурас биз үчүн Java компилятору тарабынан автоматтык түрдө аткарылат. Андан кийин, санап чыгууну ишке ашыруу үчүн компилятор тарабынан түзүлгөн классты -класс деп атайлы enum
, ал эми саналган типтин мүмкүн болгон маанилерин enum
-a элементтери деп атайлы.
enum
Enum мүчөлөрү статикалык жактан жеткorктүү болгон -класстын мисалдары
Элементтер -класстын enum Season (WINTER, SPRING и т.д.)
статикалык жеткorктүү инстанциялары . Алардын статикалык жеткorктүүлүгү шилтеме салыштыруу оператору аркылуу салыштырууларды жүргүзүүгө мүмкүндүк берет . Мисал: enum
Season
==
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
Enum элементинин аты жана сериялык номери
Мурда айтылгандай, ар кандайenum
-class inherits java.lang.Enum
, анда бардык санауулар үчүн пайдалуу бир катар ыкмалар бар. Мисал:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
чыгаруу болот:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
Методдор name()
жана бул toString()
жерде көрсөтүлгөн ordinal()
. Методдордун семантикасы ачык көрүнүп турат. enum
Бул ыкмалар класстан тукум кууп өткөнүн белгилей кетүү керек java.lang.Enum
. Элементти enum
анын атын сап көрсөтүүсү боюнча алуу Көбүнчө элементти enum
анын саптуу чагылдырылышы боюнча алуу милдети келип чыгат. Бул максаттар үчүн, ар бир enum
-класста компилятор автоматтык түрдө атайын статикалык ыкманы түзөт: , ал ге барабар ат менен public static EnumClass valueOf(String name)
санап чыгуу элементин кайтарат . Колдонуу мисалы: EnumClass
name
String name = "WINTER";
Season season = Season.valueOf(name);
Кодду аткаруунун натыйжасында сезон өзгөрмөсү ге барабар болот Season.WINTER
. Элемент табылбаса, IllegalArgumentException ыргытыларын , ал эми ал name
барабар болсо null
, NullPointerException ыргытыларын эске алыңыз . Айтмакчы, бул көп учурда унутулуп калат. Эмнегедир көптөр эгер функция бир аргумент алып, белгилүү шарттарда IllegalArgumentException ыргытса , анда аны ал жакка өткөрүп жатканда , сөзсүз түрдө IllegalArgumentExceptionnull
да ыргытылат деп бекем ишенет . Бирок мунун мааниси жок. уланталы. Санактын бардык элементтерин алуу Кээде иштөө учурунда -класстын бардык элементтеринин тизмесин алуу керек болот . Бул максаттар үчүн, компилятор ар бир -класста метод жаратат . Колдонуу мисалы: enum
enum
public static EnumClass[] values()
System.out.println(Arrays.toString(Season.values()));
Биз төмөнкү натыйжаны алабыз:
[WINTER, SPRING, SUMMER, AUTUMN]
Класста метод valueOf()
да, метод да аныкталбаганын эске алыңыз . Анын ордуна, алар -класс компиляцияланганда компилятор тарабынан автоматтык түрдө кошулат . -класска өз ыкмаларыңызды кошуу Сизде -класска да, анын элементтерине да өз ыкмаларыңызды кошуу мүмкүнчүлүгү бар : Ошол эле, бирок полиморфизм менен: Акыркы мисалда мурастын колдонулушу көрсөтүлөт . Бул тууралуу кийинчерээк. Java'да мурастоо класс иерархиясын ишке ашырууга мүмкүндүк берет, анын an objectтери бир инстанцияда түзүлөт жана статикалык жактан жеткorктүү. Бул учурда, элементтер өздөрүнүн конструкторлорун камтышы мүмкүн. Мисал келтирели: Бул жерде биз үч элементтен турган санап чыгууну жарыялайбыз жана . Компилятор төмөнкү класстарды жана an objectтерди түзөт: values()
java.lang.Enum
enum
enum
enum
enum
enum
enum
enum
Type
INT
INTEGER
STRING
Type
-дан алынган классjava.lang.Enum
INT
— 1-класстагы an objectтен алынганType
INTEGER
— 2-класстагы an objectтен алынганType
STRING
— 3-класстагы an objectтен алынганType
Object parse(String)
Полиморфтук метод жана конструктор менен үч туунду класс түзүлөт Type(..., boolean)
. Ошол эле учурда класстардын an objectтери бир нускада бар жана статикалык жактан жеткorктүү INT
. Муну текшере аласыз: INTEGER
STRING
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());
Биз төмөнкү натыйжаны алабыз:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
Type
Компилятор классты жана 3 nested
классты түзгөнүн көрүүгө болот Type
.
Декомпиляцияланган өндүрүш классы мурастоо менен
Type
Жогорудагыларды ырастоо үчүн, биз жогорудагы мисалдан санап чыгуунун натыйжасын сунуштайбыз :
Саноолор жана параметрдик полиморфизм
Окурман таң калышы мүмкүн: " Эмне үчүн жогорудагы типтеги тизмеде генериктерди колдонбойт? " Чындыгында Java-да генериктерди колдонуугаenum
тыюу салынган. Ошентип, төмөнкү мисал түзүлбөйт:
enum Type<T> {}
Андан ары изилдөө
Санактардын Javaда кантип иштээрин тереңирээк түшүнүү үчүн мен класстын баштапкы codeу менен таанышуунуjava.lang.Enum
, ошондой эле түзүлгөн codeду изилдөө үчүн Jad декомпиляторун колдонууну сунуштайм. Мындан тышкары, Java китепканасынын булак codeун изилдөө Javaдагы канча механизм иштээрин түшүнүү үчүн абдан зарыл жана an objectке багытталган дизайн үчүн шилтеме катары пайдалуу. Түпнуска булакка шилтеме: http://alexander.lds.lg.ua/
GO TO FULL VERSION