Enum werd geïntroduceerd in Java 1.5 als een nieuw type waarvan de velden bestaan uit een vast aantal constanten. Bijvoorbeeld, we kunnen richtingen maken als een Java Enum met vaste velden zoals EAST, WEST, NORTH, en SOUTH.
Java Enum
In deze tutorial zullen we leren hoe we een Enum kunnen maken. We zullen ook kijken naar de voordelen van het gebruik van enums in Java en de kenmerken van enum types. We zullen ook leren hoe we Java Enum
valueOf
, enum values
, EnumSet
en EnumMap
kunnen gebruiken met voorbeelden.
Voorbeeld van Java Enum
Het Java enum trefwoord wordt gebruikt om een enum type te maken. Laten we eens kijken naar het voorbeeldprogramma van de Java enum.
package com.journaldev.enums;
public enum ThreadStates {
START,
RUNNING,
WAITING,
DEAD;
}
In het bovenstaande voorbeeld is ThreadStates de enum met vaste constante velden START, RUNNING, WAITING en DEAD.
Vergelijking tussen Java Enum en Constanten
Laten we nu eens kijken hoe Java enum beter is dan normale constante velden in Java-klassen. Laten we een vergelijkbare constante klasse maken in Java.
package com.journaldev.enums;
public class ThreadStatesConstant {
public static final int START = 1;
public static final int WAITING = 2;
public static final int RUNNING = 3;
public static final int DEAD = 4;
}
Nu gaan we eens kijken hoe zowel enum als constanten worden gebruikt in een Java-programma:
/**
* This method shows the benefit of using Enum over Constants
*/
private static void benefitsOfEnumOverConstants() {
//Enum-waarden zijn vast
simpleEnumExample(ThreadStates.START);
simpleEnumExample(ThreadStates.WAITING);
simpleEnumExample(ThreadStates.RUNNING);
simpleEnumExample(ThreadStates.DEAD);
simpleEnumExample(null);
simpleConstantsExample(1);
simpleConstantsExample(2);
simpleConstantsExample(3);
simpleConstantsExample(4);
//we kunnen elk constant int doorgeven
simpleConstantsExample(5);
}
private static void simpleEnumExample(ThreadStates th) {
if(th == ThreadStates.START) System.out.println("Thread started");
else if (th == ThreadStates.WAITING) System.out.println("Thread is waiting");
else if (th == ThreadStates.RUNNING) System.out.println("Thread is running");
else System.out.println("Thread is dead");
}
private static void simpleConstantsExample(int i) {
if(i == ThreadStatesConstant.START) System.out.println("Thread started");
else if (i == ThreadStatesConstant.WAITING) System.out.println("Thread is waiting");
else if (i == ThreadStatesConstant.RUNNING) System.out.println("Thread is running");
else System.out.println("Thread is dead");
}
Als we naar het bovenstaande voorbeeld kijken, hebben we twee risico’s bij het gebruik van constanten die worden opgelost door de enum.
- We kunnen elk int-constante doorgeven aan de methode
simpleConstantsExample
maar we kunnen alleen vaste waarden doorgeven aan simpleEnumExample, dus het biedt typeveiligheid. - We kunnen de waarde van de int-constanten wijzigen in de klasse
ThreadStatesConstant
maar het bovenstaande programma zal geen uitzondering veroorzaken. Ons programma werkt mogelijk niet zoals verwacht, maar als we de enum-constanten wijzigen, krijgen we een compileerfout die elk mogelijk runtime-probleem wegneemt.
Java Enum-methoden
Latenn we nu meer functies van Java Enum zien aan de hand van een voorbeeld.
package com.journaldev.enums;
import java.io.Closeable;
import java.io.IOException;
/**
* This Enum example shows all the things we can do with Enum types
*
*/
public enum ThreadStatesEnum implements Closeable{
START(1){
@Override
public String toString(){
return "START implementation. Priority="+getPriority();
}
@Override
public String getDetail() {
return "START";
}
},
RUNNING(2){
@Override
public String getDetail() {
return "RUNNING";
}
},
WAITING(3){
@Override
public String getDetail() {
return "WAITING";
}
},
DEAD(4){
@Override
public String getDetail() {
return "DEAD";
}
};
private int priority;
public abstract String getDetail();
//Enum-constructors moeten altijd privé zijn.
private ThreadStatesEnum(int i){
priority = i;
}
//Enum kan methoden hebben
public int getPriority(){
return this.priority;
}
public void setPriority(int p){
this.priority = p;
}
//Enum kan functies overschrijven
@Override
public String toString(){
return "Default ThreadStatesConstructors implementation. Priority="+getPriority();
}
@Override
public void close() throws IOException {
System.out.println("Close of Enum");
}
}
Belangrijke punten van Java Enum
Hier zijn enkele belangrijke punten voor Enums in Java.
- Alle java enumeraties breiden impliciet de klasse
java.lang.Enum
uit, die de klasse Object uitbreidt en de interfaces Serializable en Comparable implementeert. We kunnen dus geen enkele klasse uitbreiden in een enumeratie. - Aangezien enumeratie een trefwoord is, kunnen we de pakketnaam er niet mee eindigen, bijvoorbeeld
com.journaldev.enum
is geen geldige pakketnaam. - Een enumeratie kan interfaces implementeren. Zoals in het bovenstaande enumeratievoorbeeld, implementeert het de interface
Closeable
. - De constructors van een enumeratie zijn altijd privé.
- We kunnen geen instantie van een enumeratie maken met behulp van de nieuwe operator.
- We kunnen abstracte methoden in java enumeraties declareren, waarna alle enumeratievelden de abstracte methode moeten implementeren. In het bovenstaande voorbeeld is
getDetail()
de abstracte methode en hebben alle enumeratievelden deze geïmplementeerd. - We kunnen een methode in een enumeratie definiëren en de enumeratievelden kunnen deze ook overschrijven. Bijvoorbeeld, de
toString()
-methode is gedefinieerd in de enumeratie en het enumeratieveld START heeft deze overschreven. - Java enumeratievelden hebben een namespace, we kunnen enumeratievelden alleen gebruiken met de klassenaam zoals
ThreadStates.START
- Enumeraties kunnen worden gebruikt in een switch statement, we zullen dit in actie zien in het latere deel van deze tutorial.
- We kunnen een bestaande enum uitbreiden zonder enige bestaande functionaliteit te breken. Bijvoorbeeld, we kunnen een nieuw veld NEW toevoegen aan de ThreadStates enum zonder enige bestaande functionaliteit te beïnvloeden.
- Aangezien enum-velden constanten zijn, is de Java-best practice om ze in hoofdletters en met een underscore voor spaties te schrijven. Bijvoorbeeld EAST, WEST, EAST_DIRECTION, enzovoort.
- Enum-constanten zijn impliciet static en final
- Enum-constanten zijn final, maar de variabele kan nog steeds worden gewijzigd. Bijvoorbeeld, we kunnen de
setPriority()
methode gebruiken om de prioriteit van enum-constanten te wijzigen. We zullen dit zien in het gebruik in het onderstaande voorbeeld. - Aangezien enum-constanten final zijn, kunnen we ze veilig vergelijken met behulp van de “==” operator en de equals() methoden. Beide zullen hetzelfde resultaat hebben.
Java EnumSet, EnumMap, valueOf()
Nu we de meeste kenmerken van Enum kennen, laten we eens kijken naar een voorbeeld van een Java Enum-programma. Daarna zullen we nog wat meer kenmerken van een enum leren.
package com.journaldev.enums;
import java.io.IOException;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Set;
public class JavaEnumExamples {
public static void main(String[] args) throws IOException {
usingEnumMethods();
usingEnumValueOf();
usingEnumValues();
usingEnumInSwitch(ThreadStatesEnum.START);
usingEnumInSwitch(ThreadStatesEnum.DEAD);
usingEnumMap();
usingEnumSet();
}
private static void usingEnumSet() {
EnumSet enumSet = EnumSet.allOf(ThreadStatesEnum.class);
for(ThreadStatesEnum tsenum : enumSet){
System.out.println("Using EnumSet, priority = "+tsenum.getPriority());
}
}
private static void usingEnumMap() {
EnumMap<ThreadStatesEnum, String> enumMap = new EnumMap<ThreadStatesEnum,String>(ThreadStatesEnum.class);
enumMap.put(ThreadStatesEnum.START, "Thread is started");
enumMap.put(ThreadStatesEnum.RUNNING, "Thread is running");
enumMap.put(ThreadStatesEnum.WAITING, "Thread is waiting");
enumMap.put(ThreadStatesEnum.DEAD, "Thread is dead");
Set keySet = enumMap.keySet();
for(ThreadStatesEnum key : keySet){
System.out.println("key="+key.toString()+":: value="+enumMap.get(key));
}
}
private static void usingEnumInSwitch(ThreadStatesEnum th) {
switch (th){
case START:
System.out.println("START thread");
break;
case WAITING:
System.out.println("WAITING thread");
break;
case RUNNING:
System.out.println("RUNNING thread");
break;
case DEAD:
System.out.println("DEAD thread");
}
}
private static void usingEnumValues() {
ThreadStatesEnum[] thArray = ThreadStatesEnum.values();
for(ThreadStatesEnum th : thArray){
System.out.println(th.toString() + "::priority="+th.getPriority());
}
}
private static void usingEnumValueOf() {
ThreadStatesEnum th = Enum.valueOf(ThreadStatesEnum.class, "START");
System.out.println("th priority="+th.getPriority());
}
private static void usingEnumMethods() throws IOException {
ThreadStatesEnum thc = ThreadStatesEnum.DEAD;
System.out.println("priority is:"+thc.getPriority());
thc = ThreadStatesEnum.DEAD;
System.out.println("Using overriden method."+thc.toString());
thc = ThreadStatesEnum.START;
System.out.println("Using overriden method."+thc.toString());
thc.setPriority(10);
System.out.println("Enum Constant variable changed priority value="+thc.getPriority());
thc.close();
}
}
Voordat we andere belangrijke kenmerken van enum uitleggen, laten we eerst de uitvoer van het bovenstaande programma zien.
priority is:4
Using overriden method.Default ThreadStatesConstructors implementation. Priority=4
Using overriden method.START implementation. Priority=1
Enum Constant variable changed priority value=10
Close of Enum
th priority=10
START implementation. Priority=10::priority=10
Default ThreadStatesConstructors implementation. Priority=2::priority=2
Default ThreadStatesConstructors implementation. Priority=3::priority=3
Default ThreadStatesConstructors implementation. Priority=4::priority=4
START thread
DEAD thread
key=START:: value=Thread is started
key=RUNNING:: value=Thread is running
key=WAITING:: value=Thread is waiting
key=DEAD:: value=Thread is dead
Using EnumSet, priority = 10
Using EnumSet, priority = 2
Using EnumSet, priority = 3
Using EnumSet, priority = 4
Belangrijke punten
- De methode
usingEnumMethods()
laat zien hoe je een enum-object kunt maken en hoe we de methoden ervan kunnen gebruiken. Het toont ook het gebruik van de methodesetPriority(int i)
om de variabele van de enum te veranderen. - De methode
usingEnumValueOf()
laat het gebruik zien vanjava.util.Enum
valueOf(enumType, name)
waarmee we een enum-object kunnen maken vanuit een tekenreeks. Het werpt eenIllegalArgumentException
op als het gespecificeerde enum-type geen constante heeft met de opgegeven naam, of het gespecificeerde klassenobject geen enum-type vertegenwoordigt. Het werpt ook eenNullPointerException
op als een van de argumenten null is. - De methode
usingEnumValues()
toont het gebruik van de values()-methode die een array retourneert met alle waarden van de enum in de volgorde waarin ze zijn gedeclareerd. Merk op dat deze methode automatisch wordt gegenereerd door de Java-compiler voor elke enum. Je zult de implementatie van values() niet vinden in de klassejava.util.Enum
. - De methode
usingEnumInSwitch()
laat zien hoe enum-constanten kunnen worden gebruikt in een switch-case. - De methode
usingEnumMap()
laat het gebruik zien van java.util.EnumMap, die is geïntroduceerd in de Java 1.5-collectiekader.EnumMap
is een map-implementatie voor gebruik met enum-type sleutels. Alle sleutels in een enum-map moeten afkomstig zijn van één enkel enum-type dat expliciet of impliciet wordt gespecificeerd wanneer de map wordt gemaakt. We kunnen null niet als sleutel gebruiken voor EnumMap en EnumMap is niet gesynchroniseerd. usingEnumSet()
methode toont het gebruik van java.util.EnumSet, wat een Set-implementatie is voor gebruik met enum-types. Alle elementen in een enum-set moeten afkomstig zijn van één enkel enum-type dat wordt gespecificeerd, expliciet of impliciet, wanneer de set wordt gemaakt. EnumSet is niet gesynchroniseerd en null-elementen zijn niet toegestaan. Het biedt ook enkele nuttige methoden zoalscopyOf(Collection<E> c)
,of(E first, E... rest)
encomplementOf(EnumSet<E> s)
.
U kunt alle voorbeelden bekijken op onze GitHub Repository.
Referentie: Oracle Doc
Source:
https://www.digitalocean.com/community/tutorials/java-enum