Pripájanie hodnôt k Java Enum

1. Úvod

Java enum typ poskytuje jazykovo podporovaný spôsob vytvárania a používania konštantných hodnôt. Definovaním konečnej množiny hodnôt sa enum je bezpečnejšia pre typ ako konštantné literálne premenné ako String alebo int.

Avšak enum hodnoty musia byť platnými identifikátormia je nám odporúčané používať SCREAMING_SNAKE_CASE podľa konvencie.

Vzhľadom na tieto obmedzenia the enum samotná hodnota nie je vhodná pre reťazce čitateľné človekom alebo pre hodnoty mimo reťazca.

V tomto výučbe použijeme enumFunkcie ako trieda Java umožňujú pripojiť požadované hodnoty.

2. Používanie Javy Enum ako trieda

Často tvoríme enum ako jednoduchý zoznam hodnôt. Napríklad tu sú prvé dva riadky periodickej tabuľky ako jednoduché enum:

verejný výčet Element {H, HE, LI, BE, B, C, N, O, F, NE}

Pomocou vyššie uvedenej syntaxe sme vytvorili desať statických, posledných inštancií súboru enum menovaný Element. Aj keď je to veľmi efektívne, zachytili sme iba symboly prvkov. A hoci je veľké písmeno vhodné pre konštanty Java, nie je to tak, ako bežne píšeme symboly.

Ďalej nám chýbajú aj ďalšie vlastnosti prvkov periodickej tabuľky, ako napríklad názov a atómová hmotnosť.

Napriek tomu enum typ má v Jave špeciálne správanie, môžeme doň pridávať konštruktory, polia a metódy, ako to robíme v iných triedach. Z tohto dôvodu môžeme vylepšiť svoje enum aby sme zahrnuli hodnoty, ktoré potrebujeme.

3. Pridanie konštruktora a záverečné pole

Začnime pridaním názvov prvkov. Mená nastavíme na a konečné premenná pomocou konštruktora:

public enum Element {H ("Vodík"), HE ("Hélium"), // ... NE ("Neón"); verejné konečné označenie reťazca; private Element (reťazec) {this.label = label; }}

Najskôr si všimneme špeciálnu syntax v zozname deklarácií. Takto sa vyvoláva konštruktor enum typy. Aj keď je nezákonné používať Nový operátor pre enum, môžeme odovzdať argumenty konštruktora v zozname deklarácií.

Potom deklarujeme inštančnú premennú štítok. K tomu je potrebné poznamenať niekoľko vecí.

Najprv sme si vybrali štítok identifikátor namiesto názov. Aj keď členské pole názov je k dispozícii na použitie, vyberme si štítok aby nedošlo k zámene s preddefinovanými Enum.name () metóda.

Po druhé, náš štítok pole je konečné. Zatiaľ čo polia an enum nemusí byť konečné, vo väčšine prípadov nechceme, aby sa naše štítky menili. V duchu enum konštantné hodnoty, to dáva zmysel.

Nakoniec štítok pole je verejné. Preto môžeme k štítku získať priamy prístup:

System.out.println (BE.label);

Na druhej strane pole môže byť súkromné, prístupné pomocou a getLabel () metóda. Z dôvodu stručnosti bude tento článok naďalej používať štýl verejného poľa.

4. Nájdenie Java Enum Hodnoty

Java poskytuje a valueOf (reťazec) metóda pre všetkých enum typy. Vždy teda môžeme získať enum hodnota na základe deklarovaného názvu:

assertSame (Element.LI, Element.valueOf ("LI"));

Možno však budeme chcieť vyhľadať enum hodnotu aj našim poľom štítku. K tomu môžeme pridať a statický metóda:

public static Element valueOfLabel (String label) {for (Element e: values ​​()) {if (e.label.equals (label)) {return e; }} return null; }

Statická valueOfLabel () metóda iteruje Element hodnoty, kým nenájde zhodu. Vracia sa to nulový ak sa nenájde zhoda. Naopak, namiesto návratu by mohla byť hodená výnimka nulový.

Pozrime sa na krátky príklad pomocou nášho valueOfLabel () metóda:

assertSame (Element.LI, Element.valueOfLabel ("lítium"));

5. Uloženie hodnôt vyhľadávania do pamäte cache

Môžeme sa vyhnúť iterácii enum hodnoty pomocou a Mapa do medzipamäte štítky. Aby sme to dosiahli, definujeme a statická konečná Mapa a naplniť ju pri načítaní triedy:

public enum Element {// ... hodnoty enum private static final Mapa BY_LABEL = new HashMap (); static {for (Element e: values ​​()) {BY_LABEL.put (e.label, e); }} // ... polia, konštruktor, metódy public static Element valueOfLabel (reťazcový štítok) {return BY_LABEL.get (štítok); }}

V dôsledku uloženia do medzipamäte enum hodnoty sú iterované iba raza valueOfLabel () metóda je zjednodušená.

Ako alternatívu môžeme lenivo zostaviť medzipamäť pri prvom prístupe do priečinka valueOfLabel () metóda. V takom prípade musí byť prístup k mape synchronizovaný, aby sa zabránilo problémom so súbežnosťou.

6. Priloženie viacerých hodnôt

The Enum konštruktor môže prijať viac hodnôt. Na ilustráciu pridajme atómové číslo ako int a atómová hmotnosť ako a plavák:

public enum Element {H ("Vodík", 1, 1,008f), HE ("Hélium", 2, 4,0026f), // ... NE ("Neón", 10, 20,180f); súkromná statická konečná mapa BY_LABEL = nová HashMap (); súkromná statická konečná mapa BY_ATOMIC_NUMBER = nová HashMap (); súkromná statická konečná mapa BY_ATOMIC_WEIGHT = nová HashMap (); static {for (Element e: values ​​()) {BY_LABEL.put (e.label, e); BY_ATOMIC_NUMBER.put (e.atomicNumber, e); BY_ATOMIC_WEIGHT.put (e.atomicWeight, e); }} verejné konečné označenie reťazca; verejné konečné int atomicNumber; verejná konečná plavák atomicWeight; private Element (String label, int atomicNumber, float atomicWeight) {this.label = label; this.atomicNumber = atomicNumber; this.atomicWeight = atomicWeight; } verejný statický prvok valueOfLabel (reťazcový štítok) {návrat BY_LABEL.get (štítok); } public static Element valueOfAtomicNumber (int number) {return BY_ATOMIC_NUMBER.get (number); } public static Element valueOfAtomicWeight (plávajúca váha) {return BY_ATOMIC_WEIGHT.get (váha); }}

Podobne môžeme do súboru pridať akékoľvek hodnoty, ktoré chceme enum, ako sú napríklad správne veľké a malé písmená, „He“, „Li“ a „Be“.

Okrem toho môžeme pridať vypočítané hodnoty k našim enum pridaním metód na vykonávanie operácií.

7. Ovládanie rozhrania

V dôsledku pridania polí a metód k nášmu enum, zmenili sme jeho verejné rozhranie. Preto je náš kód, ktorý využíva jadro Enumnázov() a hodnota() metódami, nebude si vedomý našich nových oblastí.

The statickýhodnota() metóda je pre nás už definovaná jazykom Java. Preto nemôžeme poskytnúť svoje vlastné hodnota() implementácia.

Podobne pretože Enum.name () metóda je konečné, tiež to nemôžeme prepísať.

Výsledkom je, že neexistuje praktický spôsob, ako využiť naše ďalšie polia pomocou štandardu Enum API. Namiesto toho sa pozrime na niekoľko rôznych spôsobov, ako odhaliť naše polia.

7.1. Naliehavé natiahnuť()

Naliehavé natiahnuť() môže byť alternatívou k prvému stavu názov():

@Override public String toString () {return this.label; }

Predvolene, Enum.toString () vráti rovnakú hodnotu ako Enum.name ().

7.2. Implementácia rozhrania

The enum typu v Jave môže implementovať rozhrania. Aj keď tento prístup nie je taký všeobecný ako Enum API, rozhrania nám pomáhajú generalizovať.

Uvažujme o tomto rozhraní:

verejné rozhranie Označené {Štítok reťazca (); }

Pre konzistenciu s Enum.name () metóda, naša štítok () metóda nemá a dostať predpona.

A pretože valueOfLabel () metóda je statický, nezahŕňame ho do nášho rozhrania.

Nakoniec môžeme rozhranie implementovať do našej enum:

public enum Element implementuje Labeled {// ... @Override public String label () {return label; } // ...}

Jednou z výhod tohto prístupu je, že: Označené rozhranie je možné použiť na akúkoľvek triedu, nielen enum typy. Namiesto spoliehania sa na generické Enum API, máme teraz viac kontextovo špecifické API.

8. Záver

V tomto článku sme preskúmali mnoho funkcií Java Enum implementácia. Pridaním konštruktorov, polí a metód vidíme, že enum dokáže oveľa viac ako doslovné konštanty.

Celý zdrojový kód tohto článku nájdete ako vždy na GitHub.